{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div align=\"right\" style=\"text-align:right\"><i>Peter Norvig<br>May 2020</i></div>\n",
    "\n",
    "# Equilength Number Expressions\n",
    "\n",
    "The internet [claims](https://www.reddit.com/r/Showerthoughts/comments/3h8wpx/four_is_the_only_number_that_has_the_same_amount/):\n",
    "\n",
    "> ***Four is the only number that has the same amount of letters as its value.*** \n",
    "\n",
    "We'll call \"*four*\" an **equilength number**. Languages other than English have different equilength numbers. In Italian there's \"tre\", in German  \"vrei\", in Spanish and Portuguese \"cinco\", and in Hanyu Pinyin Chinese \"èr\" and \"sān\". French does not have an equilength number. \n",
    "\n",
    "There are also **equilength number expressions** such as \"two plus nine\": its value is 11 and there are 11 letters in the expression (spaces and hyphens don't count). What other integers besides 11 have equilength expressions? In English and in other languages? This notebook will partially answer these questions.  \n",
    "\n",
    "# Defining the Language of Numbers\n",
    "\n",
    "I start by defining the namedtuple class `Language` and the convenience function `language`, which will be used to succintly declare the names of arithmetic operators and numbers. Use `language` like this:\n",
    "\n",
    "    mini = language('Mini', {add: 'plus, and', mul: 'times'}, \n",
    "                    'zero, one, two, three, four')\n",
    "    \n",
    "This defines a language named `'Mini'` with two `operators`, addition (which can be spelled two ways, as `'plus'` or `'and'`) and multiplication (which can only be spelled `'times'`); and with five `integers`, denoted consecutively starting at zero. \n",
    "\n",
    "# The ExpTable Data Structure\n",
    "\n",
    "Internally, the key data structure is something I'll call an expression table or `ExpTable`: a dict where each value is an *expression*: a string such as `\"zero\"` or `\"(two plus nine)\"`; and each key is a tuple of two integers: the numeric value of the expression and the number of letters in the expression. The integers for the mini language defined above form this table:\n",
    "\n",
    "    {(0, 4): 'zero', (1, 3): 'one', (2, 3): 'two'}, (3, 5): 'three', (4, 4): 'four')\n",
    "    \n",
    "The key `(0, 4)` means that the expression `'zero'` has the value `0` and has `4` letters. I arrange things this way because I want to eventually build up equilength expressions, ones where the key is `(i, i)` for as many integers `i` as possible, and to do so I only need one table entry for each `(value, letters)` combination.\n",
    "Let's implement that:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import namedtuple\n",
    "from operator    import add, sub, mul, neg, truediv as div"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "ExpTable = dict # A mapping of {(value, count_of_letters): \"expression\"}\n",
    "\n",
    "Language = namedtuple('Language', 'name, operators, integers')\n",
    "\n",
    "def language(name, operators, integers) -> Language:\n",
    "    \"\"\"E.g., language({add: 'plus, and', mul: 'times'}, 'zero, one, two')\"\"\"\n",
    "    return Language(name, {op: split(operators[op]) for op in operators},\n",
    "                    exptable(enumerate(split(integers))))\n",
    "        \n",
    "def exptable(items) -> ExpTable:\n",
    "    \"\"\"Convert an iterable of (value, \"exp\") pairs to {(value, letter_count): \"exp\"}\"\"\"\n",
    "    return {(val, lettercount(exp)): exp for (val, exp) in items}\n",
    "\n",
    "def lettercount(exp) -> int: return sum(ch.isalpha() for ch in exp)\n",
    "\n",
    "def split(text, sep=',') -> list: \n",
    "    \"\"\"Split text by `sep`, stripping whitespace.\"\"\"\n",
    "    return [word.strip() for word in text.split(',')]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "mini = language('Mini', {add: 'plus, and', mul: 'times'}, \n",
    "                'zero, one, two, three, four')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Building Number Expressions\n",
    "\n",
    "I want to follow an approach similar to what I did in the [Making Numbers: Four 4s, Five 5s](Countdown.ipynb) notebook: take two entries from a table (like `{(2, 3): 'two'}` and `{(3, 5): 'three'}`) along with an operator, and combine them to make a larger expression (`{(5, 12): 'two plus three'}`). \n",
    "\n",
    "There is an infinite set of possible expressions, so  I will focus on a finite subset of expressions that have a chance of being equilength (although not afraid of making intermediate expressions that are not equilength).\n",
    "\n",
    "I'll use the following strategy to build an `ExpTable` with `expressions(language, c)`:\n",
    "  - Start with a copy of the table of integers from the language.\n",
    "  - Repeat `c` times:\n",
    "      - Add to the table all ways to `combine` an integer entry, an operator, and a table entry.\n",
    "      - Add to the table all ways to `combine` a table entry, an operator, and an integer entry.\n",
    "  - Given the table; use `equilength` to pull just the equilength expressions from the table.\n",
    "        \n",
    "    \n",
    "Note this doesn't form all possible expressions: it gives me **branching** expression trees but not **bushy** expression trees. Consider the two trees below; each with eight leaves (integers) and seven internal nodes (operators):\n",
    "- **Below left: a bushy tree** that could have been formed by `c=3` iterations of combining any two table entries, <br>e.g. `(((a+b)+(c+d))+((e+f)+(g+h)))`\n",
    "- **Below right: a branching tree** formed by `c=7` iterations of combining an integer with a table entry, <br>e.g. \n",
    "`(h+((f+(e+(((a+b)+c)+d)))+g))`.\n",
    "\n",
    "\n",
    "        /\\        /\\\n",
    "       /  \\        /\\ \n",
    "      /\\  /\\      /\\\n",
    "     /\\/\\/\\/\\      /\\\n",
    "                    /\\\n",
    "                   /\\\n",
    "                  /\\\n",
    "\n",
    "Here is the code to create `expressions`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def expressions(language, c=1) -> ExpTable:\n",
    "    \"\"\"Combine language integers with table entries c times.\"\"\"\n",
    "    _, ops, ints = language\n",
    "    table = dict(ints) # Copy the language.integers table so we can modify it\n",
    "    for i in range(c):\n",
    "        table.update({**combine(ints,  ops, table), \n",
    "                      **combine(table, ops, ints)})\n",
    "    return table\n",
    "\n",
    "def combine(Ltable, operators, Rtable) -> ExpTable:\n",
    "    \"\"\"Return table like {(5, 12): \"(two plus three)\"} by combining table entries with ops.\"\"\"\n",
    "    return exptable((op(lv, rv), f'({Ltable[lv, ln]} {opname} {Rtable[rv, rn]})')\n",
    "                    for (rv, rn) in Rtable\n",
    "                    for op in operators\n",
    "                    if not (rv == 0 and op == div) # Don't divide by zero\n",
    "                    for (lv, ln) in Ltable\n",
    "                    for opname in operators[op])\n",
    "\n",
    "def equilength(table) -> dict:\n",
    "    \"\"\"Return only table expressions that evaluate to n and have n letters.\"\"\"\n",
    "    return {n: table[n, n] for (v, n) in sorted(table) if n == v}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{(0, 4): 'zero', (1, 3): 'one', (2, 3): 'two', (3, 5): 'three', (4, 4): 'four'}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expressions(mini, 0) # The table after zero iterations of `combine`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{(0, 4): 'zero',\n",
       " (1, 3): 'one',\n",
       " (2, 3): 'two',\n",
       " (3, 5): 'three',\n",
       " (4, 4): 'four',\n",
       " (0, 12): '(zero times two)',\n",
       " (0, 11): '(zero and zero)',\n",
       " (1, 11): '(one times one)',\n",
       " (1, 10): '(zero and one)',\n",
       " (2, 11): '(one times two)',\n",
       " (2, 10): '(zero and two)',\n",
       " (3, 13): '(one times three)',\n",
       " (3, 12): '(zero and three)',\n",
       " (4, 12): '(one times four)',\n",
       " (4, 11): '(zero and four)',\n",
       " (0, 13): '(zero times four)',\n",
       " (0, 14): '(zero times three)',\n",
       " (2, 9): '(one and one)',\n",
       " (3, 10): '(one plus two)',\n",
       " (3, 9): '(one and two)',\n",
       " (5, 11): '(one plus four)',\n",
       " (5, 10): '(one and four)',\n",
       " (4, 10): '(two plus two)',\n",
       " (4, 9): '(two and two)',\n",
       " (5, 12): '(two plus three)',\n",
       " (6, 11): '(two plus four)',\n",
       " (6, 10): '(two and four)',\n",
       " (6, 13): '(two times three)',\n",
       " (8, 12): '(two times four)',\n",
       " (6, 14): '(three plus three)',\n",
       " (7, 13): '(three plus four)',\n",
       " (7, 12): '(three and four)',\n",
       " (9, 15): '(three times three)',\n",
       " (12, 14): '(three times four)',\n",
       " (8, 11): '(four and four)',\n",
       " (16, 13): '(four times four)'}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expressions(mini, 1) # The table after one iteration of `combine`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{4: 'four',\n",
       " 20: '((one plus four) times four)',\n",
       " 24: '(((two and two) and two) times four)',\n",
       " 25: '(((two and four) times four) and one)',\n",
       " 26: '(((two and four) times four) plus two)',\n",
       " 27: '(((one and four) and four) times three)',\n",
       " 28: '(((zero and three) and four) times four)',\n",
       " 29: '(((three plus four) times four) plus one)',\n",
       " 30: '(((two times three) and four) times three)',\n",
       " 31: '(((three plus four) times four) plus three)'}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "equilength(expressions(mini, 3)) # The equilength expressions after 3 iterations of `combine`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The code above solves the problem, but I added the code below to make the solution look prettier:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show(language, c):\n",
    "    \"\"\"Summarize and show the equilength expressions from this language.\"\"\"\n",
    "    table = expressions(language, c)\n",
    "    equis = equilength(table)\n",
    "    print(f'{language.name} has {len(equis)} equilengths: {describe(set(equis))}')\n",
    "    print(f'     from {len(table):,d} table entries in {c} iterations') \n",
    "    return equis\n",
    "    \n",
    "def describe(numbers: set) -> str:\n",
    "    \"\"\"Describe a set of integers in a shorthand way.\n",
    "    E.g. shorthand({1, 2, 3, 4, 5, 6, 86, 99}) => '1-6, 86, 99'.\"\"\"\n",
    "    formats = []\n",
    "    M = max(numbers) + 2\n",
    "    while numbers:\n",
    "        missing = next(i for i in range(min(numbers), M) if i not in numbers)\n",
    "        g = set(range(min(numbers), missing)) # Group of consecutive numbers\n",
    "        formats.append(f'{min(g)}' + (f'-{max(g)}' if len(g) > 1 else ''))\n",
    "        numbers = numbers - g\n",
    "    return ', '.join(formats)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Mini Language Equilength Expressions\n",
    "\n",
    "We'll see what we can do with just the mini language:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mini has 48 equilengths: 4, 20, 24-69\n",
      "     from 32,517 table entries in 7 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{4: 'four',\n",
       " 20: '((one plus four) times four)',\n",
       " 24: '(((two and two) and two) times four)',\n",
       " 25: '(((two and four) times four) and one)',\n",
       " 26: '(((two and four) times four) plus two)',\n",
       " 27: '(((one and four) and four) times three)',\n",
       " 28: '(((zero and three) and four) times four)',\n",
       " 29: '(((three plus four) times four) plus one)',\n",
       " 30: '(((two times three) and four) times three)',\n",
       " 31: '(((three plus four) times four) plus three)',\n",
       " 32: '((((one and one) and two) plus four) times four)',\n",
       " 33: '((((one and two) and four) and four) times three)',\n",
       " 34: '((((two and four) and four) times three) and four)',\n",
       " 35: '((((two and two) plus four) times four) plus three)',\n",
       " 36: '((((one times two) plus three) and four) times four)',\n",
       " 37: '((((three and four) and four) times three) plus four)',\n",
       " 38: '(((((two and two) and four) times four) and two) and four)',\n",
       " 39: '(((((four and four) times four) and one) and two) and four)',\n",
       " 40: '(((((zero and one) and one) and four) plus four) times four)',\n",
       " 41: '(((((four and four) times four) and one) and four) plus four)',\n",
       " 42: '(((((four and four) times four) and two) plus four) plus four)',\n",
       " 43: '(((((four and four) times four) and three) and four) plus four)',\n",
       " 44: '(((((zero and zero) and three) plus four) plus four) times four)',\n",
       " 45: '(((((three times three) times four) and one) plus four) and four)',\n",
       " 46: '(((((four times four) plus three) times two) plus four) plus four)',\n",
       " 47: '(((((three times three) and four) times three) plus four) and four)',\n",
       " 48: '(((((zero times three) and one) times three) times four) times four)',\n",
       " 49: '((((((two and four) plus four) times four) plus one) plus four) and four)',\n",
       " 50: '((((((two and four) and four) and four) times three) plus four) plus four)',\n",
       " 51: '((((((two and four) and four) times four) plus three) plus four) plus four)',\n",
       " 52: '((((((zero times three) plus one) and four) and four) plus four) times four)',\n",
       " 53: '((((((three and four) and four) plus four) times three) plus four) plus four)',\n",
       " 54: '(((((((two and four) and four) times four) and two) plus four) and four) and four)',\n",
       " 55: '(((((((one and two) and four) and four) times four) and three) and four) plus four)',\n",
       " 56: '(((((((zero and zero) and one) times two) plus four) and four) and four) times four)',\n",
       " 57: '(((((((three and four) and four) times four) and one) plus four) plus four) and four)',\n",
       " 58: '(((((((one and four) times four) and three) times two) plus four) plus four) and four)',\n",
       " 59: '(((((((three and four) and four) times four) and three) and four) plus four) plus four)',\n",
       " 60: '(((((((zero and zero) and one) times three) plus four) plus four) plus four) times four)',\n",
       " 61: '(((((((one and four) times three) times three) and four) plus four) plus four) plus four)',\n",
       " 62: '(((((((three plus four) times three) plus four) times two) and four) plus four) plus four)',\n",
       " 63: '(((((((three times three) plus four) plus four) times three) plus four) and four) and four)',\n",
       " 64: '(((((((zero times three) plus one) times one) times one) times four) times four) times four)',\n",
       " 65: '(((((((three times three) and three) plus three) and four) times three) plus four) plus four)',\n",
       " 66: '(((((((three plus three) times three) times three) plus two) plus three) plus three) and four)',\n",
       " 67: '(((((((zero times three) times three) plus three) and four) times three) times three) and four)',\n",
       " 68: '(((((((zero times three) times three) plus three) times three) plus four) plus four) times four)',\n",
       " 69: '(((((((zero times three) plus three) plus three) times three) plus four) times three) plus three)'}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(mini, 7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Defining Multiple Languages\n",
    "\n",
    "Now some real languages: English, Spanish, French, Italian, Pinyin Chinese and German, with integers from 0 to 30."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "english = language('English', \n",
    "    {add: 'plus, and, added to', sub: 'minus, less, take away', mul: 'times, multiplied by',\n",
    "    div: 'divided by, over', lambda x, y: y - x: 'subtracted from'},\n",
    "    '''zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, \n",
    "    twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty,\n",
    "    twenty-one, twenty-two, twenty-three, twenty-four, twenty-five, twenty-six,\n",
    "    twenty-seven, twenty-eight, twenty-nine, thirty''')\n",
    "\n",
    "spanish = language('Spanish', \n",
    "    {add: 'más', sub: 'menos', mul: 'por', div: 'dividido entre, dividido por'},\n",
    "    '''cero, uno, dos, tres, cuatro, cinco, seis, siete, ocho, nueve, diez, once, doce, \n",
    "    trece, catorce, quince, dieciséis, diecisiete, dieciocho, diecinueve, veinte, veintiuno, \n",
    "    veintidós, veintitrés, veinticuatro, veinticinco, veintiséis, veintisiete, veintiocho,\n",
    "    veintinueve, treinta''')\n",
    "\n",
    "french = language('French',\n",
    "    {add: 'plus, et', sub: 'moins', mul: 'multiplié par, fois', div: 'divisé par, sur'},\n",
    "    '''zéro, un, deux, trois, quatre, cinq, six, sept, huit, neuf, dix, onze, douze, \n",
    "    treize, quatorze, quinze, seize, dix-sept, dix-huit, dix-neuf, vingt, vingt et un,\n",
    "    vingt-deux, vingt-trois, vingt-quatre, vingt-cinq, vingt-six, vingt-sept, vingt-huit,\n",
    "    vingt-neuf, trente''')\n",
    "\n",
    "italian = language('Italian',\n",
    "    {add: 'piu', sub: 'meno', mul: 'per', div: 'diviso'},\n",
    "    '''zero, uno, due, tre, quattro, cinque, sei, sette, otto, nove, dieci, undici, dodici,\n",
    "    tredici, quattrodici, quindici, sedici, dicisette, diciotto, dicinove, venti,\n",
    "    ventiuno, ventidue, ventitre, ventiquattro, venticinque, ventisei, ventisette,\n",
    "    ventotto, ventinove, trenta''')\n",
    "\n",
    "chinese = language('Chinese',\n",
    "    {add: 'jiā', sub: 'jiǎn', mul: 'chéng', div: 'chú, chú yǐ'},\n",
    "    '''ling, yī, èr, sān, sì, wŭ, liù, qī, bā, jiŭ, shí, shí yī, shí èr, shí sān, \n",
    "    shí sì, shí wǔ, shí liù, shí qī, shí bā, shí jiŭ, èr shí, èr shí yī, èr shí èr, \n",
    "    èr shí sān, èr shí sì, èr shí wŭ, èr shí liù, èr shí qī, èr shí bā, èr shí jiŭ, sān shí''')\n",
    "\n",
    "german = language('German',\n",
    "    {add: 'und, plus', sub: 'weniger, minus', mul: 'mal, multipliziert', div: 'durch'},\n",
    "    '''null, eins, zwei, drei, vier, fünf, sechs, sieben, acht, neun, zehn, elf, \n",
    "    zwölf, dreizehn, vierzehn, funfzehn, sechszehn, siebzehn, achtzehn, neunzehn, \n",
    "    zwanzig, einundzwanzig, zweiundzwanzig, dreiundzwanzig, vierundzwanzig,\n",
    "    fünfundzwanzig, sechsundzwanzig, siebenundzwanzig, achtundzwanzig, \n",
    "    neunundzwanzig, dreiβig''')\n",
    "\n",
    "languages = english, spanish, french, italian, chinese, german"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Equilength Numbers\n",
    "\n",
    "Let's start with the equilength numbers for each language:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "English {4: 'four'}\n",
      "Spanish {5: 'cinco'}\n",
      "French  {}\n",
      "Italian {3: 'tre'}\n",
      "Chinese {2: 'èr', 3: 'sān'}\n",
      "German  {4: 'vier'}\n"
     ]
    }
   ],
   "source": [
    "for L in languages:\n",
    "    print(f'{L.name:7} {equilength(L.integers)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I'm also interested in the average number of letters over the first 31 integers for each language:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "English 6.8 letters/integer\n",
      "Spanish 7.0 letters/integer\n",
      "French  6.2 letters/integer\n",
      "Italian 6.7 letters/integer\n",
      "Chinese 4.9 letters/integer\n",
      "German  8.2 letters/integer\n"
     ]
    }
   ],
   "source": [
    "for L in languages:\n",
    "    avg = sum(n for (v, n) in L.integers) / len(L.integers)\n",
    "    print(f'{L.name:7} {avg:.1f} letters/integer')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we'll look at each language in turn, seeing what equilength number expressions we can get in just a few seconds of computation, with `c=2` iterations of `combine`:\n",
    "\n",
    "# English\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "English has 47 equilengths: 4, 10-54, 56\n",
      "     from 418,515 table entries in 2 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{4: 'four',\n",
       " 10: '(zero and ten)',\n",
       " 11: '(two plus nine)',\n",
       " 12: '(one and eleven)',\n",
       " 13: '(one plus twelve)',\n",
       " 14: '(one and thirteen)',\n",
       " 15: '(one times fifteen)',\n",
       " 16: '(three and thirteen)',\n",
       " 17: '(one times seventeen)',\n",
       " 18: '((one and six) and eleven)',\n",
       " 19: '((one less two) and twenty)',\n",
       " 20: '((zero less ten) and thirty)',\n",
       " 21: '((one minus ten) plus thirty)',\n",
       " 22: '((one minus nine) plus thirty)',\n",
       " 23: '((three minus ten) plus thirty)',\n",
       " 24: '((ten less sixteen) plus thirty)',\n",
       " 25: '((five times eleven) less thirty)',\n",
       " 26: '((seven times eight) minus thirty)',\n",
       " 27: '((nine divided by ten) times thirty)',\n",
       " 28: '((two times twenty-nine) less thirty)',\n",
       " 29: '((twenty-nine and thirty) less thirty)',\n",
       " 30: '((ten less ten) subtracted from thirty)',\n",
       " 31: '((nine less ten) subtracted from thirty)',\n",
       " 32: '((eight less ten) subtracted from thirty)',\n",
       " 33: '((seven minus ten) subtracted from thirty)',\n",
       " 34: '((six take away ten) subtracted from thirty)',\n",
       " 35: '((ten minus fifteen) subtracted from thirty)',\n",
       " 36: '((nine minus fifteen) subtracted from thirty)',\n",
       " 37: '((ten minus seventeen) subtracted from thirty)',\n",
       " 38: '((eleven less nineteen) subtracted from thirty)',\n",
       " 39: '((twenty-one less thirty) subtracted from thirty)',\n",
       " 40: '((twenty take away thirty) subtracted from thirty)',\n",
       " 41: '((fifteen minus twenty-six) subtracted from thirty)',\n",
       " 42: '((eighteen take away thirty) subtracted from thirty)',\n",
       " 43: '((seventeen take away thirty) subtracted from thirty)',\n",
       " 44: '((fourteen minus twenty-eight) subtracted from thirty)',\n",
       " 45: '((twelve take away twenty-seven) subtracted from thirty)',\n",
       " 46: '((thirteen take away twenty-nine) subtracted from thirty)',\n",
       " 47: '((twenty-six subtracted from nine) subtracted from thirty)',\n",
       " 48: '((twenty-eight subtracted from ten) subtracted from thirty)',\n",
       " 49: '((twenty-eight subtracted from nine) subtracted from thirty)',\n",
       " 50: '((twenty-eight subtracted from eight) subtracted from thirty)',\n",
       " 51: '((twenty-six subtracted from four) subtracted from twenty-nine)',\n",
       " 52: '((twenty-six subtracted from three) subtracted from twenty-nine)',\n",
       " 53: '((twenty-eight subtracted from four) subtracted from twenty-nine)',\n",
       " 54: '((twenty-eight subtracted from three) subtracted from twenty-nine)',\n",
       " 56: '((twenty-four subtracted from twenty-six) multiplied by twenty-eight)'}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(english, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Spanish"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Spanish has 41 equilengths: 5, 10-12, 14-42, 44-46, 48-50, 52, 54\n",
      "     from 220,630 table entries in 2 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{5: 'cinco',\n",
       " 10: '(uno por diez)',\n",
       " 11: '(cero más once)',\n",
       " 12: '(tres más nueve)',\n",
       " 14: '(cero más catorce)',\n",
       " 15: '(quince menos cero)',\n",
       " 16: '(cero más dieciséis)',\n",
       " 17: '(cero más diecisiete)',\n",
       " 18: '((uno más dos) más quince)',\n",
       " 19: '((uno más tres) más quince)',\n",
       " 20: '((dos menos uno) por veinte)',\n",
       " 21: '((uno por uno) por veintiuno)',\n",
       " 22: '((dos menos diez) más treinta)',\n",
       " 23: '((tres menos diez) más treinta)',\n",
       " 24: '((seis por nueve) menos treinta)',\n",
       " 25: '((diez menos quince) más treinta)',\n",
       " 26: '((diez menos catorce) más treinta)',\n",
       " 27: '((diez menos doce) más veintinueve)',\n",
       " 28: '((doce menos trece) más veintinueve)',\n",
       " 29: '((cuatro menos tres) por veintinueve)',\n",
       " 30: '((veintiuno menos veinte) por treinta)',\n",
       " 31: '((veinte menos diecinueve) más treinta)',\n",
       " 32: '((treinta menos veintiocho) más treinta)',\n",
       " 33: '((treinta menos veintisiete) más treinta)',\n",
       " 34: '((veintiséis menos veintidós) más treinta)',\n",
       " 35: '((veintiocho menos veintitrés) más treinta)',\n",
       " 36: '((dieciocho dividido por quince) por treinta)',\n",
       " 37: '((veinticuatro menos diecisiete) más treinta)',\n",
       " 38: '((veintiséis dividido por dos) más veinticinco)',\n",
       " 39: '((veintiséis dividido entre veinte) por treinta)',\n",
       " 40: '((veintiocho dividido por veintiuno) por treinta)',\n",
       " 41: '((diecisiete dividido entre uno) más veinticuatro)',\n",
       " 42: '((veintiuno dividido entre catorce) por veintiocho)',\n",
       " 44: '(once dividido entre (seis dividido por veinticuatro))',\n",
       " 45: '(veintiuno dividido por (catorce dividido por treinta))',\n",
       " 46: '(veinte dividido entre (diez dividido entre veintitrés))',\n",
       " 48: '(veinte dividido entre (diez dividido entre veinticuatro))',\n",
       " 49: '(veintiocho dividido entre (doce dividido entre veintiuno))',\n",
       " 50: '(veinticinco dividido por (catorce dividido por veintiocho))',\n",
       " 52: '(veinticuatro dividido entre (doce dividido entre veintiséis))',\n",
       " 54: '(veintisiete dividido entre (catorce dividido entre veintiocho))'}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(spanish, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# French"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "French has 40 equilengths: 7-42, 44-46, 48\n",
      "     from 279,648 table entries in 2 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{7: '(un et six)',\n",
       " 8: '(un et sept)',\n",
       " 9: '(neuf sur un)',\n",
       " 10: '(un plus neuf)',\n",
       " 11: '(trois et huit)',\n",
       " 12: '(quatre et huit)',\n",
       " 13: '((un et deux) et dix)',\n",
       " 14: '(un fois quatorze)',\n",
       " 15: '((un et deux) et douze)',\n",
       " 16: '((un sur un) fois seize)',\n",
       " 17: '((un fois un) plus seize)',\n",
       " 18: '((un sur un) fois dix-huit)',\n",
       " 19: '((dix moins onze) et vingt)',\n",
       " 20: '((six sur neuf) fois trente)',\n",
       " 21: '((deux moins onze) et trente)',\n",
       " 22: '((huit moins seize) et trente)',\n",
       " 23: '((dix moins dix-sept) et trente)',\n",
       " 24: '((douze sur quinze) fois trente)',\n",
       " 25: '((douze moins dix-sept) et trente)',\n",
       " 26: '((quinze moins dix-neuf) et trente)',\n",
       " 27: '((trois fois dix-neuf) moins trente)',\n",
       " 28: '((vingt-huit fois trente) sur trente)',\n",
       " 29: '((vingt moins vingt et un) plus trente)',\n",
       " 30: '((trente moins vingt-neuf) fois trente)',\n",
       " 31: '((vingt-neuf moins vingt-huit) et trente)',\n",
       " 32: '((seize sur quinze) multiplié par trente)',\n",
       " 33: '((vingt-deux divisé par vingt) fois trente)',\n",
       " 34: '((dix-sept sur quinze) multiplié par trente)',\n",
       " 35: '((vingt et un divisé par dix-huit) fois trente)',\n",
       " 36: '((trente sur vingt-cinq) multiplié par trente)',\n",
       " 37: '((quatre multiplié par seize) moins vingt-sept)',\n",
       " 38: '((dix-neuf sur douze) multiplié par vingt-quatre)',\n",
       " 39: '((quatre multiplié par dix-sept) moins vingt-neuf)',\n",
       " 40: '((vingt divisé par treize) multiplié par vingt-six)',\n",
       " 41: '((trois multiplié par vingt-trois) moins vingt-huit)',\n",
       " 42: '((vingt et un divisé par quinze) multiplié par trente)',\n",
       " 44: '((vingt-deux divisé par treize) multiplié par vingt-six)',\n",
       " 45: '((vingt-cinq divisé par quinze) multiplié par vingt-sept)',\n",
       " 46: '((vingt-six moins vingt-quatre) multiplié par vingt-trois)',\n",
       " 48: '((vingt-quatre moins vingt-deux) multiplié par vingt-quatre)'}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(french, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Italian"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Italian has 32 equilengths: 3, 9-13, 15-40\n",
      "     from 127,985 table entries in 2 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{3: 'tre',\n",
       " 9: '(tre piu sei)',\n",
       " 10: '(uno piu nove)',\n",
       " 11: '(uno piu dieci)',\n",
       " 12: '(uno per dodici)',\n",
       " 13: '(uno per tredici)',\n",
       " 15: '(zero piu quindici)',\n",
       " 16: '(quattro piu dodici)',\n",
       " 17: '(tre piu quattrodici)',\n",
       " 18: '((uno meno tre) piu venti)',\n",
       " 19: '((zero meno uno) piu venti)',\n",
       " 20: '((nove meno otto) per venti)',\n",
       " 21: '((uno meno dieci) piu trenta)',\n",
       " 22: '((tre meno undici) piu trenta)',\n",
       " 23: '((nove meno sedici) piu trenta)',\n",
       " 24: '((otto diviso dieci) per trenta)',\n",
       " 25: '((cinque per undici) meno trenta)',\n",
       " 26: '((nove meno dodici) piu ventinove)',\n",
       " 27: '((dicisette meno venti) piu trenta)',\n",
       " 28: '((tredici meno quindici) piu trenta)',\n",
       " 29: '((ventidue meno ventitre) piu trenta)',\n",
       " 30: '((ventinove meno ventotto) per trenta)',\n",
       " 31: '((ventotto diviso ventotto) piu trenta)',\n",
       " 32: '((ventinove meno ventisette) piu trenta)',\n",
       " 33: '((ventiquattro meno ventiuno) piu trenta)',\n",
       " 34: '((ventisette meno ventidue) piu ventinove)',\n",
       " 35: '((ventotto diviso ventiquattro) per trenta)',\n",
       " 36: '((diciotto diviso quattrodici) per ventotto)',\n",
       " 37: '((venticinque meno quattrodici) piu ventisei)',\n",
       " 38: '((ventiquattro meno quattrodici) piu ventotto)',\n",
       " 39: '((ventiquattro meno quattrodici) piu ventinove)',\n",
       " 40: '((ventiquattro diviso quindici) per venticinque)'}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(italian, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chinese"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chinese has 28 equilengths: 2-3, 7-32\n",
      "     from 166,807 table entries in 2 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{2: 'èr',\n",
       " 3: 'sān',\n",
       " 7: '(èr jiā wŭ)',\n",
       " 8: '(èr jiā liù)',\n",
       " 9: '(sān jiā liù)',\n",
       " 10: '(yī chéng shí)',\n",
       " 11: '(shí bā jiǎn qī)',\n",
       " 12: '(yī chéng shí èr)',\n",
       " 13: '(yī chéng shí sān)',\n",
       " 14: '(èr shí sì jiǎn shí)',\n",
       " 15: '(sān shí jiǎn shí wǔ)',\n",
       " 16: '((sì jiǎn bā) jiā èr shí)',\n",
       " 17: '((qī jiǎn shí) jiā èr shí)',\n",
       " 18: '((yī jiǎn bā) jiā èr shí wŭ)',\n",
       " 19: '((qī chéng qī) jiǎn sān shí)',\n",
       " 20: '((liù chú jiŭ) chéng sān shí)',\n",
       " 21: '((qī chú yǐ shí) chéng sān shí)',\n",
       " 22: '((bā jiǎn shí wǔ) jiā èr shí jiŭ)',\n",
       " 23: '((shí yī jiǎn shí bā) jiā sān shí)',\n",
       " 24: '((shí èr chú shí wǔ) chéng sān shí)',\n",
       " 25: '((èr shí jiǎn èr shí wŭ) jiā sān shí)',\n",
       " 26: '((shí sān chú shí sì) chéng èr shí bā)',\n",
       " 27: '((èr shí qī chéng sān shí) chú sān shí)',\n",
       " 28: '((èr shí qī jiǎn èr shí jiŭ) jiā sān shí)',\n",
       " 29: '((èr shí yī jiǎn èr shí) chéng èr shí jiŭ)',\n",
       " 30: '((èr shí jiŭ chú èr shí jiŭ) chéng sān shí)',\n",
       " 31: '(èr shí wŭ jiǎn (èr shí sān jiǎn èr shí jiŭ))',\n",
       " 32: '(èr shí liù jiǎn (èr shí sān jiǎn èr shí jiŭ))'}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(chinese, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# German"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "German has 48 equilengths: 4, 11-13, 15-57, 63\n",
      "     from 238,787 table entries in 2 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{4: 'vier',\n",
       " 11: '(null plus elf)',\n",
       " 12: '(eins mal zwölf)',\n",
       " 13: '(eins plus zwölf)',\n",
       " 15: '(eins mal funfzehn)',\n",
       " 16: '(eins mal sechszehn)',\n",
       " 17: '(eins plus sechszehn)',\n",
       " 18: '((zwei und fünf) plus elf)',\n",
       " 19: '((zwei und fünf) und zwölf)',\n",
       " 20: '((null mal elf) und zwanzig)',\n",
       " 21: '(null plus einundzwanzig)',\n",
       " 22: '((drei minus elf) und dreiβig)',\n",
       " 23: '((vier minus elf) plus dreiβig)',\n",
       " 24: '((sechs mal neun) minus dreiβig)',\n",
       " 25: '((eins minus sechs) plus dreiβig)',\n",
       " 26: '((elf minus funfzehn) und dreiβig)',\n",
       " 27: '((drei mal neunzehn) minus dreiβig)',\n",
       " 28: '((zwölf minus vierzehn) und dreiβig)',\n",
       " 29: '((zwölf minus dreizehn) plus dreiβig)',\n",
       " 30: '((zwanzig minus neunzehn) mal dreiβig)',\n",
       " 31: '((zwanzig minus neunzehn) plus dreiβig)',\n",
       " 32: '((sechszehn durch funfzehn) mal dreiβig)',\n",
       " 33: '((zwanzig weniger siebzehn) plus dreiβig)',\n",
       " 34: '((zwanzig weniger sechszehn) plus dreiβig)',\n",
       " 35: '((vier mal sechszehn) minus neunundzwanzig)',\n",
       " 36: '((dreiβig durch fünfundzwanzig) mal dreiβig)',\n",
       " 37: '((fünfundzwanzig minus achtzehn) und dreiβig)',\n",
       " 38: '((fünfundzwanzig minus siebzehn) plus dreiβig)',\n",
       " 39: '((neunundzwanzig weniger zwanzig) plus dreiβig)',\n",
       " 40: '((zwanzig durch funfzehn) multipliziert dreiβig)',\n",
       " 41: '((siebenundzwanzig minus sechszehn) plus dreiβig)',\n",
       " 42: '((siebenundzwanzig weniger funfzehn) plus dreiβig)',\n",
       " 43: '((einundzwanzig weniger sieben) und neunundzwanzig)',\n",
       " 44: '((siebenundzwanzig minus zwölf) plus neunundzwanzig)',\n",
       " 45: '((drei multipliziert fünfundzwanzig) weniger dreiβig)',\n",
       " 46: '((fünf multipliziert funfzehn) weniger neunundzwanzig)',\n",
       " 47: '((siebenundzwanzig minus sieben) plus siebenundzwanzig)',\n",
       " 48: '((fünf multipliziert funfzehn) weniger siebenundzwanzig)',\n",
       " 49: '((eins multipliziert dreiundzwanzig) und sechsundzwanzig)',\n",
       " 50: '((eins multipliziert dreiundzwanzig) und siebenundzwanzig)',\n",
       " 51: '((eins multipliziert vierundzwanzig) plus siebenundzwanzig)',\n",
       " 52: '((drei multipliziert siebenundzwanzig) minus neunundzwanzig)',\n",
       " 53: '((drei multipliziert sechsundzwanzig) weniger fünfundzwanzig)',\n",
       " 54: '((neunundzwanzig minus siebenundzwanzig) mal siebenundzwanzig)',\n",
       " 55: '((drei multipliziert siebenundzwanzig) weniger sechsundzwanzig)',\n",
       " 56: '((neunundzwanzig weniger fünfundzwanzig) multipliziert vierzehn)',\n",
       " 57: '((neunundzwanzig weniger sechsundzwanzig) multipliziert neunzehn)',\n",
       " 63: '((siebenundzwanzig weniger vierundzwanzig) multipliziert einundzwanzig)'}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "show(german, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Infinite Additions\n",
    "\n",
    "I have a feeling that there are an infinite number of equilength expressions in most languages. But how to prove it? One way is to show an infinite pattern. For example, in English we have: \"four (and six)<sup><i>k</i></sup>\" meaning \"four\", \"four and six\", \"four and six and six\", ... Because \"and six\" has 6 letters, we can add the phrase an arbitrary number of times, generating the pattern..\n",
    "\n",
    "I'll search for more such patterns in all our languages:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'English': {6: 'and six ...', 8: 'and eight ...', 10: 'added to ten ...'},\n",
       " 'Spanish': {},\n",
       " 'French': {8: 'plus huit ...'},\n",
       " 'Italian': {6: 'piu sei ...', 14: 'piu quattrodici ...'},\n",
       " 'Chinese': {5: 'jiā wŭ ...', 6: 'jiā liù ...'},\n",
       " 'German': {8: 'plus acht ...'}}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def infinite_equilengths(language):\n",
    "    return {v: f'{plus} {number} ...' for plus in language.operators[add] \n",
    "            for (v, n), number in language.integers.items() \n",
    "            if v == lettercount(plus + number)}\n",
    "\n",
    "{L.name: infinite_equilengths(L) for L in languages}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extended Languages\n",
    "\n",
    "To find more equilength expressions I will need to search a larger portion of the search space. I can think of three approaches:\n",
    "\n",
    "1. Go beyond `c=2` to `c=3` or `c=4` iterations.\n",
    "2. Instead of always combining an integer with a table entry, allow the combination of two table entries.\n",
    "3. Continue to restrict combinations to an integer and a table entry, but seed the integers with more entries that are bigger in both value and number of letters.\n",
    "\n",
    "My intution is that (1) and (2) will give me \"bushier\" expressions that are unlikely to help much. They will have lots of different numerical values, but the new expressions will have roughly the same number of letters in them as the previous expressions. \n",
    "\n",
    "Therefore, I'm going to try approach (3), which has the added advantage that I don't have to  alter `word_expessions` or `combine`. I'm going to define an `extended` language were we add to the `language.integers` field. I could just add regular integers, perhaps going up to a hundred rather than just thirty. But the problem is that an integer like \"ninety\" has a lot fewer letters than its value; I think there would be an imbalance. Instead I'll add *pseudo-integers:* for each integer (like `\"two\"`) in the base language, the extended language will have new expressions like `(two plus two plus two...)`. The idea is that these will be better building blocks when we `combine` an integer with a table entry."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def extended(language, repeats=6) -> Language:\n",
    "    \"\"\"Extend language by adding \"repeated\" integers, like \"two plus two plus two\".\"\"\"\n",
    "    name, ops, ints = language\n",
    "    new_ints = exptable((i * r, '(' + f' {op} '.join([exp] * r) + ')')\n",
    "                        for r in range(2, repeats + 1)\n",
    "                        for (i, _), exp in ints.items()\n",
    "                        for op in ops[add])\n",
    "    return Language('Extended ' + name, ops, {**ints, **new_ints})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, here are the extended integers for the `mini` language, with up to 3 repeats:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{(0, 4): 'zero',\n",
       " (1, 3): 'one',\n",
       " (2, 3): 'two',\n",
       " (3, 5): 'three',\n",
       " (4, 4): 'four',\n",
       " (0, 12): '(zero plus zero)',\n",
       " (0, 11): '(zero and zero)',\n",
       " (2, 10): '(one plus one)',\n",
       " (2, 9): '(one and one)',\n",
       " (4, 10): '(two plus two)',\n",
       " (4, 9): '(two and two)',\n",
       " (6, 14): '(three plus three)',\n",
       " (6, 13): '(three and three)',\n",
       " (8, 12): '(four plus four)',\n",
       " (8, 11): '(four and four)',\n",
       " (0, 20): '(zero plus zero plus zero)',\n",
       " (0, 18): '(zero and zero and zero)',\n",
       " (3, 17): '(one plus one plus one)',\n",
       " (3, 15): '(one and one and one)',\n",
       " (6, 17): '(two plus two plus two)',\n",
       " (6, 15): '(two and two and two)',\n",
       " (9, 23): '(three plus three plus three)',\n",
       " (9, 21): '(three and three and three)',\n",
       " (12, 20): '(four plus four plus four)',\n",
       " (12, 18): '(four and four and four)'}"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "extended(mini, 3).integers"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Efficiency of `expressions`\n",
    "\n",
    "Come to think of it, I will alter `expressions` after all. Not to accomodate some new strategy, but rather to be more efficient. The previous version of `expressions` tries to combine each integer on either the left or the right of an existing expression in `table`. That's inefficient for two reasons:\n",
    "- On the first iteration, we're combining an integer with an integer; there's only one way to do that, so trying two ways is redundant.\n",
    "- On subsequent iterations, given, say, the integer \"two\" and the expression \"(one plus two)\", I want both \"(two minus (one plus two))\" and \"((one plus two) minus two)\" because the respective values are -1 and 1, but it is redundant to combine them both ways with addition (or multiplication), because the resulting value is 5 (or 6) either way, because addition (or multiplication) is commutative. So we will restrict the second call to `combine` to only noncommutative operations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def expressions(language, c=1) -> ExpTable:\n",
    "    \"\"\"Combine language integers with table c times.\"\"\"\n",
    "    _, ops, ints = language\n",
    "    table = dict(ints) # Copy the language.integers table so we can modify it\n",
    "    if c >= 1:\n",
    "        table.update(combine(ints,  ops, table))\n",
    "    for i in range(1, c):\n",
    "        table.update({**combine(ints,  ops, table), \n",
    "                      **combine(table, noncommutative(ops), ints)})\n",
    "    return table\n",
    "\n",
    "def noncommutative(ops: dict) -> dict: \n",
    "    \"\"\"Copy `ops` but omit the commutative operators.\"\"\"\n",
    "    return {op: ops[op] for op in ops if op not in (add, mul)}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see how well the extended languages perform:\n",
    "\n",
    "# Extended English"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extended English has 5 equilengths: 4, 14, 21, 24, 32\n",
      "     from 488 table entries in 0 iterations\n",
      "CPU times: user 2.72 ms, sys: 89 µs, total: 2.81 ms\n",
      "Wall time: 2.79 ms\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{4: 'four',\n",
       " 14: '(seven plus seven)',\n",
       " 21: '(seven and seven and seven)',\n",
       " 24: '(six plus six plus six plus six)',\n",
       " 32: '(eight plus eight plus eight plus eight)'}"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time show(extended(english), 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extended English has 150 equilengths: 4, 10-148, 150-154, 156, 158, 162-163, 168\n",
      "     from 275,310 table entries in 1 iterations\n",
      "CPU times: user 26.1 s, sys: 282 ms, total: 26.4 s\n",
      "Wall time: 26.8 s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{4: 'four',\n",
       " 10: '(zero and ten)',\n",
       " 11: '(two plus nine)',\n",
       " 12: '(one and eleven)',\n",
       " 13: '(one plus twelve)',\n",
       " 14: '(one and thirteen)',\n",
       " 15: '(one times fifteen)',\n",
       " 16: '(four and (six and six))',\n",
       " 17: '(five plus (six and six))',\n",
       " 18: '(zero and (nine and nine))',\n",
       " 19: '(one plus (nine plus nine))',\n",
       " 20: '(zero and (ten added to ten))',\n",
       " 21: '(three plus (nine plus nine))',\n",
       " 22: '(zero and (eleven and eleven))',\n",
       " 23: '(one plus (eleven plus eleven))',\n",
       " 24: '(six plus (six plus six plus six))',\n",
       " 25: '(seven and (six plus six plus six))',\n",
       " 26: '(eight plus (six plus six plus six))',\n",
       " 27: '(zero and (nine plus nine plus nine))',\n",
       " 28: '(one added to (nine and nine and nine))',\n",
       " 29: '(five plus (six and six and six and six))',\n",
       " 30: '(six and (six plus six plus six plus six))',\n",
       " 31: '((two and two) plus (nine and nine and nine))',\n",
       " 32: '(eight and (six plus six plus six plus six))',\n",
       " 33: '(zero and (eleven plus eleven plus eleven))',\n",
       " 34: '(four and (six and six and six and six and six))',\n",
       " 35: '(five plus (six and six and six and six and six))',\n",
       " 36: '(zero added to (nine and nine and nine and nine))',\n",
       " 37: '(five plus (eight and eight and eight and eight))',\n",
       " 38: '(two subtracted from (ten and ten and ten and ten))',\n",
       " 39: '(nine plus (six plus six plus six plus six plus six))',\n",
       " 40: '(four and (six and six and six and six and six and six))',\n",
       " 41: '(five plus (six and six and six and six and six and six))',\n",
       " 42: '(thirty and (two and two and two and two and two and two))',\n",
       " 43: '(thirteen plus (six plus six plus six plus six plus six))',\n",
       " 44: '(four and (eight and eight and eight and eight and eight))',\n",
       " 45: '(nine and (six plus six plus six plus six plus six plus six))',\n",
       " 46: '(one added to (nine plus nine plus nine plus nine plus nine))',\n",
       " 47: '(eleven and (six plus six plus six plus six plus six plus six))',\n",
       " 48: '(twelve plus (six plus six plus six plus six plus six plus six))',\n",
       " 49: '(thirteen and (six plus six plus six plus six plus six plus six))',\n",
       " 50: '(ten subtracted from (ten and ten and ten and ten and ten and ten))',\n",
       " 51: '(nine subtracted from (ten and ten and ten and ten and ten and ten))',\n",
       " 52: '(eight subtracted from (ten and ten and ten and ten and ten and ten))',\n",
       " 53: '(twenty-three and (five and five and five and five and five and five))',\n",
       " 54: '(one multiplied by (nine and nine and nine and nine and nine and nine))',\n",
       " 55: '(ten plus (nine added to nine added to nine added to nine added to nine))',\n",
       " 56: '((two and two) subtracted from (ten and ten and ten and ten and ten and ten))',\n",
       " 57: '(three subtracted from (ten plus ten plus ten plus ten plus ten plus ten))',\n",
       " 58: '((two plus two) plus (nine plus nine plus nine plus nine plus nine plus nine))',\n",
       " 59: '(eleven and (eight plus eight plus eight plus eight plus eight plus eight))',\n",
       " 60: '(zero and (ten added to ten added to ten added to ten added to ten added to ten))',\n",
       " 61: '(thirteen and (eight plus eight plus eight plus eight plus eight plus eight))',\n",
       " 62: '((four added to four) and (nine plus nine plus nine plus nine plus nine plus nine))',\n",
       " 63: '((one added to one added to one) added to (ten and ten and ten and ten and ten and ten))',\n",
       " 64: '(four added to (ten added to ten added to ten added to ten added to ten added to ten))',\n",
       " 65: '(twenty-three plus (seven plus seven plus seven plus seven plus seven plus seven))',\n",
       " 66: '(one multiplied by (eleven and eleven and eleven and eleven and eleven and eleven))',\n",
       " 67: '(twenty-five added to (seven plus seven plus seven plus seven plus seven plus seven))',\n",
       " 68: '((one added to one) plus (eleven and eleven and eleven and eleven and eleven and eleven))',\n",
       " 69: '((one and one and one) and (eleven and eleven and eleven and eleven and eleven and eleven))',\n",
       " 70: '((two plus two) plus (eleven plus eleven plus eleven plus eleven plus eleven plus eleven))',\n",
       " 71: '(seventeen and (nine added to nine added to nine added to nine added to nine added to nine))',\n",
       " 72: '((zero and zero and zero) and (twelve and twelve and twelve and twelve and twelve and twelve))',\n",
       " 73: '((one plus one plus one) plus (fourteen and fourteen and fourteen and fourteen and fourteen))',\n",
       " 74: '((four added to four) and (eleven plus eleven plus eleven plus eleven plus eleven plus eleven))',\n",
       " 75: '((one plus one plus one) added to (twelve and twelve and twelve and twelve and twelve and twelve))',\n",
       " 76: '((one and one and one and one) plus (twelve and twelve and twelve and twelve and twelve and twelve))',\n",
       " 77: '(twenty-three added to (nine added to nine added to nine added to nine added to nine added to nine))',\n",
       " 78: '(one multiplied by (thirteen and thirteen and thirteen and thirteen and thirteen and thirteen))',\n",
       " 79: '(seven and (twelve added to twelve added to twelve added to twelve added to twelve added to twelve))',\n",
       " 80: '((twenty and twenty) subtracted from (twenty and twenty and twenty and twenty and twenty and twenty))',\n",
       " 81: '((one and one and one) and (thirteen and thirteen and thirteen and thirteen and thirteen and thirteen))',\n",
       " 82: '((four and four) subtracted from (fifteen and fifteen and fifteen and fifteen and fifteen and fifteen))',\n",
       " 83: '(seventeen and (eleven added to eleven added to eleven added to eleven added to eleven added to eleven))',\n",
       " 84: '((eighteen and eighteen) subtracted from (twenty and twenty and twenty and twenty and twenty and twenty))',\n",
       " 85: '((five added to five added to five added to five added to five) plus (ten and ten and ten and ten and ten and ten))',\n",
       " 86: '((seventeen and seventeen) subtracted from (twenty and twenty and twenty and twenty and twenty and twenty))',\n",
       " 87: '((one plus one plus one) added to (fourteen and fourteen and fourteen and fourteen and fourteen and fourteen))',\n",
       " 88: '((sixteen plus sixteen) subtracted from (twenty plus twenty plus twenty plus twenty plus twenty plus twenty))',\n",
       " 89: '(twenty-three added to (eleven added to eleven added to eleven added to eleven added to eleven added to eleven))',\n",
       " 90: '(eighteen subtracted from (eighteen plus eighteen plus eighteen plus eighteen plus eighteen plus eighteen))',\n",
       " 91: '(seventeen subtracted from (eighteen plus eighteen plus eighteen plus eighteen plus eighteen plus eighteen))',\n",
       " 92: '((eleven and eleven) subtracted from (nineteen and nineteen and nineteen and nineteen and nineteen and nineteen))',\n",
       " 93: '((one plus one plus one) subtracted from (sixteen plus sixteen plus sixteen plus sixteen plus sixteen plus sixteen))',\n",
       " 94: '(twenty-six subtracted from (twenty added to twenty added to twenty added to twenty added to twenty added to twenty))',\n",
       " 95: '(twenty-five subtracted from (twenty added to twenty added to twenty added to twenty added to twenty added to twenty))',\n",
       " 96: '((three and three) subtracted from (seventeen and seventeen and seventeen and seventeen and seventeen and seventeen))',\n",
       " 97: '((seventeen and seventeen and seventeen and seventeen and seventeen) added to (two and two and two and two and two and two))',\n",
       " 98: '((two plus two) subtracted from (seventeen plus seventeen plus seventeen plus seventeen plus seventeen plus seventeen))',\n",
       " 99: '(twenty-seven subtracted from (twenty-one plus twenty-one plus twenty-one plus twenty-one plus twenty-one plus twenty-one))',\n",
       " 100: '((sixteen and sixteen) subtracted from (twenty-two and twenty-two and twenty-two and twenty-two and twenty-two and twenty-two))',\n",
       " 101: '(twenty-three added to (thirteen added to thirteen added to thirteen added to thirteen added to thirteen added to thirteen))',\n",
       " 102: '((twelve added to twelve) subtracted from (twenty-one and twenty-one and twenty-one and twenty-one and twenty-one and twenty-one))',\n",
       " 103: '(eleven subtracted from (nineteen added to nineteen added to nineteen added to nineteen added to nineteen added to nineteen))',\n",
       " 104: '((twenty-six and twenty-six) subtracted from (twenty-six and twenty-six and twenty-six and twenty-six and twenty-six and twenty-six))',\n",
       " 105: '((five plus five plus five) subtracted from (twenty added to twenty added to twenty added to twenty added to twenty added to twenty))',\n",
       " 106: '((twenty-five and twenty-five) subtracted from (twenty-six and twenty-six and twenty-six and twenty-six and twenty-six and twenty-six))',\n",
       " 107: '((one plus one plus one plus one plus one) added to (seventeen and seventeen and seventeen and seventeen and seventeen and seventeen))',\n",
       " 108: '((twenty-four plus twenty-four plus twenty-four) subtracted from (thirty plus thirty plus thirty plus thirty plus thirty plus thirty))',\n",
       " 109: '((one and one and one and one and one) subtracted from (nineteen plus nineteen plus nineteen plus nineteen plus nineteen plus nineteen))',\n",
       " 110: '((ten and ten and ten and ten) subtracted from (twenty-five and twenty-five and twenty-five and twenty-five and twenty-five and twenty-five))',\n",
       " 111: '((twenty-three plus twenty-three plus twenty-three) subtracted from (thirty plus thirty plus thirty plus thirty plus thirty plus thirty))',\n",
       " 112: '((nineteen added to nineteen) subtracted from (twenty-five and twenty-five and twenty-five and twenty-five and twenty-five and twenty-five))',\n",
       " 113: '((one and one and one and one and one) and (eighteen added to eighteen added to eighteen added to eighteen added to eighteen added to eighteen))',\n",
       " 114: '((nine and nine and nine and nine) subtracted from (twenty-five and twenty-five and twenty-five and twenty-five and twenty-five and twenty-five))',\n",
       " 115: '((eleven added to eleven added to eleven added to eleven added to eleven) plus (ten added to ten added to ten added to ten added to ten added to ten))',\n",
       " 116: '((twenty-nine added to twenty-nine) subtracted from (twenty-nine and twenty-nine and twenty-nine and twenty-nine and twenty-nine and twenty-nine))',\n",
       " 117: '((three added to three added to three) subtracted from (twenty-one plus twenty-one plus twenty-one plus twenty-one plus twenty-one plus twenty-one))',\n",
       " 118: '((twenty-eight added to twenty-eight) subtracted from (twenty-nine and twenty-nine and twenty-nine and twenty-nine and twenty-nine and twenty-nine))',\n",
       " 119: '(twenty-five subtracted from (twenty-four added to twenty-four added to twenty-four added to twenty-four added to twenty-four added to twenty-four))',\n",
       " 120: '((twenty-seven plus twenty-seven) subtracted from (twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine))',\n",
       " 121: '((eleven plus eleven plus eleven plus eleven plus eleven) plus (eleven added to eleven added to eleven added to eleven added to eleven added to eleven))',\n",
       " 122: '(sixteen subtracted from (twenty-three added to twenty-three added to twenty-three added to twenty-three added to twenty-three added to twenty-three))',\n",
       " 123: '((nineteen added to nineteen added to nineteen) subtracted from (thirty added to thirty added to thirty added to thirty added to thirty added to thirty))',\n",
       " 124: '((sixteen added to sixteen) subtracted from (twenty-six added to twenty-six added to twenty-six added to twenty-six added to twenty-six added to twenty-six))',\n",
       " 125: '((five plus five plus five plus five plus five) subtracted from (twenty-five and twenty-five and twenty-five and twenty-five and twenty-five and twenty-five))',\n",
       " 126: '((twelve plus twelve plus twelve) subtracted from (twenty-seven plus twenty-seven plus twenty-seven plus twenty-seven plus twenty-seven plus twenty-seven))',\n",
       " 127: '((seventeen added to seventeen added to seventeen added to seventeen added to seventeen) plus (seven plus seven plus seven plus seven plus seven plus seven))',\n",
       " 128: '((ten added to ten added to ten added to ten) subtracted from (twenty-eight and twenty-eight and twenty-eight and twenty-eight and twenty-eight and twenty-eight))',\n",
       " 129: '((fifteen added to fifteen added to fifteen) subtracted from (twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine))',\n",
       " 130: '((twenty-two and twenty-two) subtracted from (twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine))',\n",
       " 131: '((five added to five added to five added to five added to five) subtracted from (twenty-six and twenty-six and twenty-six and twenty-six and twenty-six and twenty-six))',\n",
       " 132: '((fourteen added to fourteen added to fourteen) subtracted from (twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine plus twenty-nine))',\n",
       " 133: '((eleven plus eleven plus eleven plus eleven plus eleven) plus (thirteen added to thirteen added to thirteen added to thirteen added to thirteen added to thirteen))',\n",
       " 134: '((fourteen and fourteen) subtracted from (twenty-seven added to twenty-seven added to twenty-seven added to twenty-seven added to twenty-seven added to twenty-seven))',\n",
       " 135: '((nine plus nine plus nine) subtracted from (twenty-seven added to twenty-seven added to twenty-seven added to twenty-seven added to twenty-seven added to twenty-seven))',\n",
       " 136: '((sixteen added to sixteen) subtracted from (twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight))',\n",
       " 137: '((seven plus seven plus seven plus seven plus seven) added to (seventeen added to seventeen added to seventeen added to seventeen added to seventeen added to seventeen))',\n",
       " 138: '((ten added to ten added to ten) subtracted from (twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight))',\n",
       " 139: '((seventeen added to seventeen added to seventeen added to seventeen added to seventeen) added to (nine added to nine added to nine added to nine added to nine added to nine))',\n",
       " 140: '((four added to four added to four added to four) subtracted from (twenty-six added to twenty-six added to twenty-six added to twenty-six added to twenty-six added to twenty-six))',\n",
       " 141: '((eleven added to eleven added to eleven) subtracted from (twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine))',\n",
       " 142: '((two added to two added to two added to two) subtracted from (twenty-five added to twenty-five added to twenty-five added to twenty-five added to twenty-five added to twenty-five))',\n",
       " 143: '((five added to five added to five added to five added to five) subtracted from (twenty-eight and twenty-eight and twenty-eight and twenty-eight and twenty-eight and twenty-eight))',\n",
       " 144: '((eight added to eight added to eight) subtracted from (twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight))',\n",
       " 145: '((twenty-three added to twenty-three added to twenty-three added to twenty-three added to twenty-three) and (five added to five added to five added to five added to five added to five))',\n",
       " 146: '((two added to two added to two added to two added to two) subtracted from (twenty-six added to twenty-six added to twenty-six added to twenty-six added to twenty-six added to twenty-six))',\n",
       " 147: '((twenty-seven plus twenty-seven plus twenty-seven plus twenty-seven plus twenty-seven plus twenty-seven) take away (three added to three added to three added to three added to three))',\n",
       " 148: '((four added to four added to four added to four added to four) subtracted from (twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight))',\n",
       " 150: '((three plus three plus three plus three plus three plus three) subtracted from (twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight))',\n",
       " 151: '((seventeen added to seventeen added to seventeen added to seventeen added to seventeen) added to (eleven added to eleven added to eleven added to eleven added to eleven added to eleven))',\n",
       " 152: '((four added to four added to four added to four) subtracted from (twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight))',\n",
       " 153: '((three added to three added to three added to three added to three) subtracted from (twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight plus twenty-eight))',\n",
       " 154: '((fourteen added to fourteen added to fourteen added to fourteen added to fourteen) and (fourteen added to fourteen added to fourteen added to fourteen added to fourteen added to fourteen))',\n",
       " 156: '((three added to three added to three added to three) subtracted from (twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight))',\n",
       " 158: '((two added to two added to two added to two added to two) subtracted from (twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight))',\n",
       " 162: '((two added to two added to two added to two added to two added to two) subtracted from (twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine added to twenty-nine))',\n",
       " 163: '((seventeen added to seventeen added to seventeen added to seventeen added to seventeen) added to (thirteen added to thirteen added to thirteen added to thirteen added to thirteen added to thirteen))',\n",
       " 168: '((twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight added to twenty-eight) take away (zero added to zero added to zero added to zero added to zero added to zero))'}"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time show(extended(english), 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extended Spanish"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extended Spanish has 77 equilengths: 5, 10-12, 14-22, 24-61, 63-73, 76-83, 85, 87-88, 92-93, 96-97\n",
      "     from 77,695 table entries in 1 iterations\n",
      "CPU times: user 1.49 s, sys: 16.9 ms, total: 1.5 s\n",
      "Wall time: 1.51 s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{5: 'cinco',\n",
       " 10: '(uno por diez)',\n",
       " 11: '(cero más once)',\n",
       " 12: '(tres más nueve)',\n",
       " 14: '(cero más catorce)',\n",
       " 15: '(quince menos cero)',\n",
       " 16: '(doce más (dos más dos))',\n",
       " 17: '(uno más (ocho más ocho))',\n",
       " 18: '(seis más (seis más seis))',\n",
       " 19: '(uno más (nueve más nueve))',\n",
       " 20: '(cuatro más (ocho más ocho))',\n",
       " 21: '(siete más (siete más siete))',\n",
       " 22: '(cuatro más (nueve más nueve))',\n",
       " 24: '(uno por (ocho más ocho más ocho))',\n",
       " 25: '(veintinueve menos (dos más dos))',\n",
       " 26: '(veintiséis menos (cero más cero))',\n",
       " 27: '(uno por (nueve más nueve más nueve))',\n",
       " 28: '((once más once más once) menos cinco)',\n",
       " 29: '((once más once más once) menos cuatro)',\n",
       " 30: '(quince más (cinco más cinco más cinco))',\n",
       " 31: '((veintidós más veintidós) menos trece)',\n",
       " 32: '(cero más (ocho más ocho más ocho más ocho))',\n",
       " 33: '(nueve más (seis más seis más seis más seis))',\n",
       " 34: '(veintiséis más (dos más dos más dos más dos))',\n",
       " 35: '(siete por (uno más uno más uno más uno más uno))',\n",
       " 36: '(cero más (nueve más nueve más nueve más nueve))',\n",
       " 37: '(nueve más (siete más siete más siete más siete))',\n",
       " 38: '(veintiséis más (tres más tres más tres más tres))',\n",
       " 39: '(veintisiete más (tres más tres más tres más tres))',\n",
       " 40: '((veinte más veinte más veinte) menos (diez más diez))',\n",
       " 41: '(veintiuno más (cinco más cinco más cinco más cinco))',\n",
       " 42: '((quince más quince) más (cuatro más cuatro más cuatro))',\n",
       " 43: '((uno más uno más uno) más (diez más diez más diez más diez))',\n",
       " 44: '((dos más dos) más (ocho más ocho más ocho más ocho más ocho))',\n",
       " 45: '((veinte más veinte) más (uno más uno más uno más uno más uno))',\n",
       " 46: '(diez más (seis más seis más seis más seis más seis más seis))',\n",
       " 47: '((veintiuno más veintiuno más veintiuno) menos dieciséis)',\n",
       " 48: '((nueve más nueve) más (seis más seis más seis más seis más seis))',\n",
       " 49: '((dos más dos) más (nueve más nueve más nueve más nueve más nueve))',\n",
       " 50: '((diez más diez más diez) más (cinco más cinco más cinco más cinco))',\n",
       " 51: '((tres más tres) más (nueve más nueve más nueve más nueve más nueve))',\n",
       " 52: '(diez más (siete más siete más siete más siete más siete más siete))',\n",
       " 53: '((nueve más nueve) más (siete más siete más siete más siete más siete))',\n",
       " 54: '((tres más tres más tres) por (uno más uno más uno más uno más uno más uno))',\n",
       " 55: '((quince más quince) más (cinco más cinco más cinco más cinco más cinco))',\n",
       " 56: '((veinte más veinte más veinte más veinte) menos (ocho más ocho más ocho))',\n",
       " 57: '((cero más cero más cero) más (diecinueve más diecinueve más diecinueve))',\n",
       " 58: '(veintiocho más (cinco más cinco más cinco más cinco más cinco más cinco))',\n",
       " 59: '(veintinueve más (cinco más cinco más cinco más cinco más cinco más cinco))',\n",
       " 60: '((cero más cero más cero) más (diez más diez más diez más diez más diez más diez))',\n",
       " 61: '((dieciocho más dieciocho) más (cinco más cinco más cinco más cinco más cinco))',\n",
       " 63: '((cinco más cinco más cinco) más (ocho más ocho más ocho más ocho más ocho más ocho))',\n",
       " 64: '((veintitrés más veintitrés más veintitrés más veintitrés) menos veintiocho)',\n",
       " 65: '((cero más cero más cero más cero) más (trece más trece más trece más trece más trece))',\n",
       " 66: '((ocho más ocho más ocho) más (siete más siete más siete más siete más siete más siete))',\n",
       " 67: '((catorce más catorce más catorce) más (cinco más cinco más cinco más cinco más cinco))',\n",
       " 68: '((veintiséis más veintiséis más veintiséis) menos (dos más dos más dos más dos más dos))',\n",
       " 69: '((cinco más cinco más cinco) más (nueve más nueve más nueve más nueve más nueve más nueve))',\n",
       " 70: '((veinticinco más veinticinco) más (cuatro más cuatro más cuatro más cuatro más cuatro))',\n",
       " 71: '((veintisiete más veintisiete más veintisiete) menos (dos más dos más dos más dos más dos))',\n",
       " 72: '((veinticuatro más veinticuatro más veinticuatro) menos (cero más cero más cero más cero))',\n",
       " 73: '((dieciséis más dieciséis más dieciséis) más (cinco más cinco más cinco más cinco más cinco))',\n",
       " 76: '((diecisiete más diecisiete más diecisiete) más (cinco más cinco más cinco más cinco más cinco))',\n",
       " 77: '((dieciséis más dieciséis más dieciséis más dieciséis más dieciséis) menos (uno más uno más uno))',\n",
       " 78: '((veinticuatro más veinticuatro más veinticuatro) más (uno más uno más uno más uno más uno más uno))',\n",
       " 79: '((veinticinco más veinticinco más veinticinco más veinticinco) menos (siete más siete más siete))',\n",
       " 80: '((diez más diez más diez más diez más diez) más (cinco más cinco más cinco más cinco más cinco más cinco))',\n",
       " 81: '((veintisiete más veintisiete más veintisiete) más (cero más cero más cero más cero más cero más cero))',\n",
       " 82: '((diecisiete más diecisiete más diecisiete más diecisiete más diecisiete) menos (uno más uno más uno))',\n",
       " 83: '((veintidós más veintidós más veintidós más veintidós más veintidós) menos (nueve más nueve más nueve))',\n",
       " 85: '((veintitrés más veintitrés más veintitrés más veintitrés más veintitrés) menos (diez más diez más diez))',\n",
       " 87: '((veintiuno más veintiuno más veintiuno) más (cuatro más cuatro más cuatro más cuatro más cuatro más cuatro))',\n",
       " 88: '((veintitrés más veintitrés más veintitrés más veintitrés más veintitrés) menos (nueve más nueve más nueve))',\n",
       " 92: '((veintiocho más veintiocho más veintiocho más veintiocho más veintiocho) menos (doce más doce más doce más doce))',\n",
       " 93: '((veintisiete más veintisiete más veintisiete más veintisiete más veintisiete) menos (veintiuno más veintiuno))',\n",
       " 96: '((veinticuatro más veinticuatro más veinticuatro) más (cuatro más cuatro más cuatro más cuatro más cuatro más cuatro))',\n",
       " 97: '((veintinueve más veintinueve más veintinueve más veintinueve más veintinueve) menos (doce más doce más doce más doce))'}"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time show(extended(spanish), 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extended French"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extended French has 107 equilengths: 7-12, 14-94, 96-105, 107-111, 113-115, 119-120\n",
      "     from 163,204 table entries in 1 iterations\n",
      "CPU times: user 6.5 s, sys: 72.1 ms, total: 6.57 s\n",
      "Wall time: 6.62 s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{7: '(un et six)',\n",
       " 8: '(un et sept)',\n",
       " 9: '(neuf sur un)',\n",
       " 10: '(un plus neuf)',\n",
       " 11: '(trois et huit)',\n",
       " 12: '(quatre et huit)',\n",
       " 14: '(deux et (six et six))',\n",
       " 15: '(trois et (six et six))',\n",
       " 16: '(un fois (huit et huit))',\n",
       " 17: '(trois et (sept et sept))',\n",
       " 18: '(quinze et (un et un et un))',\n",
       " 19: '(un plus (six et six et six))',\n",
       " 20: '((zéro et zéro) et (dix et dix))',\n",
       " 21: '(six et (cinq et cinq et cinq))',\n",
       " 22: '(un plus (sept et sept et sept))',\n",
       " 23: '(dix-neuf et (un et un et un et un))',\n",
       " 24: '(un fois (six et six et six et six))',\n",
       " 25: '(vingt et (un et un et un et un et un))',\n",
       " 26: '((un et un) et (six et six et six et six))',\n",
       " 27: '(trois plus (six et six et six et six))',\n",
       " 28: '(un fois (sept et sept et sept et sept))',\n",
       " 29: '((dix et dix) et (trois et trois et trois))',\n",
       " 30: '(cinq fois (un et un et un et un et un et un))',\n",
       " 31: '(trois plus (sept et sept et sept et sept))',\n",
       " 32: '(vingt-six et (un et un et un et un et un et un))',\n",
       " 33: '(vingt-sept et (un et un et un et un et un et un))',\n",
       " 34: '(neuf et (cinq et cinq et cinq et cinq et cinq))',\n",
       " 35: '(vingt-neuf plus (un et un et un et un et un et un))',\n",
       " 36: '(six et (six plus six plus six plus six plus six))',\n",
       " 37: '(sept et (six plus six plus six plus six plus six))',\n",
       " 38: '((seize et seize) plus (un et un et un et un et un et un))',\n",
       " 39: '(neuf plus (six plus six plus six plus six plus six))',\n",
       " 40: '((dix-sept et dix-sept) et (un et un et un et un et un et un))',\n",
       " 41: '(six et (sept plus sept plus sept plus sept plus sept))',\n",
       " 42: '(zéro plus (sept et sept et sept et sept et sept et sept))',\n",
       " 43: '(trois et (huit plus huit plus huit plus huit plus huit))',\n",
       " 44: '((un et un) plus (sept et sept et sept et sept et sept et sept))',\n",
       " 45: '((cinq plus cinq plus cinq) et (six et six et six et six et six))',\n",
       " 46: '((deux et deux) et (sept et sept et sept et sept et sept et sept))',\n",
       " 47: '(vingt-deux et (cinq plus cinq plus cinq plus cinq plus cinq))',\n",
       " 48: '(un multiplié par (huit et huit et huit et huit et huit et huit))',\n",
       " 49: '((trois et trois et trois) et (huit et huit et huit et huit et huit))',\n",
       " 50: '(deux et (huit plus huit plus huit plus huit plus huit plus huit))',\n",
       " 51: '(trois et (huit plus huit plus huit plus huit plus huit plus huit))',\n",
       " 52: '((un et un et un et un) plus (huit et huit et huit et huit et huit et huit))',\n",
       " 53: '((six et six et six) plus (sept plus sept plus sept plus sept plus sept))',\n",
       " 54: '((zéro et zéro et zéro) plus (neuf et neuf et neuf et neuf et neuf et neuf))',\n",
       " 55: '(vingt-cinq et (cinq plus cinq plus cinq plus cinq plus cinq plus cinq))',\n",
       " 56: '((un plus un) plus (neuf plus neuf plus neuf plus neuf plus neuf plus neuf))',\n",
       " 57: '((trois et trois et trois) plus (huit et huit et huit et huit et huit et huit))',\n",
       " 58: '((un plus un plus un plus un) plus (neuf et neuf et neuf et neuf et neuf et neuf))',\n",
       " 59: '((onze et onze et onze et onze) plus (trois et trois et trois et trois et trois))',\n",
       " 60: '((zéro et zéro et zéro et zéro et zéro) plus (dix et dix et dix et dix et dix et dix))',\n",
       " 61: '((douze plus douze plus douze) et (cinq plus cinq plus cinq plus cinq plus cinq))',\n",
       " 62: '((quatre et quatre) plus (neuf plus neuf plus neuf plus neuf plus neuf plus neuf))',\n",
       " 63: '((dix-sept et dix-sept et dix-sept) plus (deux et deux et deux et deux et deux et deux))',\n",
       " 64: '((deux et deux et deux et deux et deux) et (neuf et neuf et neuf et neuf et neuf et neuf))',\n",
       " 65: '((vingt-cinq et vingt-cinq) plus (trois plus trois plus trois plus trois plus trois))',\n",
       " 66: '((zéro et zéro et zéro et zéro et zéro) plus (onze et onze et onze et onze et onze et onze))',\n",
       " 67: '((treize et treize et treize et treize) plus (trois et trois et trois et trois et trois))',\n",
       " 68: '((deux plus deux plus deux plus deux) et (dix plus dix plus dix plus dix plus dix plus dix))',\n",
       " 69: '((trois et trois et trois et trois et trois) et (neuf et neuf et neuf et neuf et neuf et neuf))',\n",
       " 70: '((deux et deux et deux et deux et deux) plus (dix plus dix plus dix plus dix plus dix plus dix))',\n",
       " 71: '((dix-sept plus dix-sept plus dix-sept) plus (quatre et quatre et quatre et quatre et quatre))',\n",
       " 72: '((zéro plus zéro plus zéro) et (douze plus douze plus douze plus douze plus douze plus douze))',\n",
       " 73: '((vingt et un plus vingt et un plus vingt et un) et (deux plus deux plus deux plus deux plus deux))',\n",
       " 74: '((deux plus deux plus deux plus deux) et (onze plus onze plus onze plus onze plus onze plus onze))',\n",
       " 75: '((trois et trois et trois et trois et trois) plus (dix plus dix plus dix plus dix plus dix plus dix))',\n",
       " 76: '((deux et deux et deux et deux et deux) plus (onze plus onze plus onze plus onze plus onze plus onze))',\n",
       " 77: '((dix-neuf plus dix-neuf plus dix-neuf) et (quatre plus quatre plus quatre plus quatre plus quatre))',\n",
       " 78: '((zéro et zéro et zéro et zéro et zéro) plus (treize et treize et treize et treize et treize et treize))',\n",
       " 79: '((trois et trois et trois) plus (quatorze plus quatorze plus quatorze plus quatorze plus quatorze))',\n",
       " 80: '((deux plus deux plus deux plus deux) et (douze plus douze plus douze plus douze plus douze plus douze))',\n",
       " 81: '((trois et trois et trois et trois et trois) plus (onze plus onze plus onze plus onze plus onze plus onze))',\n",
       " 82: '((deux et deux et deux et deux et deux) plus (douze plus douze plus douze plus douze plus douze plus douze))',\n",
       " 83: '((vingt-sept et vingt-sept et vingt-sept et vingt-sept) moins (cinq plus cinq plus cinq plus cinq plus cinq))',\n",
       " 84: '((zéro et zéro et zéro et zéro) plus (quatorze et quatorze et quatorze et quatorze et quatorze et quatorze))',\n",
       " 85: '((trois et trois et trois et trois et trois) plus (quatorze et quatorze et quatorze et quatorze et quatorze))',\n",
       " 86: '((deux plus deux plus deux plus deux) et (treize plus treize plus treize plus treize plus treize plus treize))',\n",
       " 87: '((trois et trois et trois et trois et trois) plus (douze plus douze plus douze plus douze plus douze plus douze))',\n",
       " 88: '((deux et deux et deux et deux et deux) plus (treize plus treize plus treize plus treize plus treize plus treize))',\n",
       " 89: '((vingt-cinq plus vingt-cinq plus vingt-cinq plus vingt-cinq plus vingt-cinq) moins (douze plus douze plus douze))',\n",
       " 90: '((deux plus deux plus deux) et (quatorze plus quatorze plus quatorze plus quatorze plus quatorze plus quatorze))',\n",
       " 91: '((vingt-neuf plus vingt-neuf plus vingt-neuf plus vingt-neuf plus vingt-neuf) moins (dix-huit et dix-huit et dix-huit))',\n",
       " 92: '((deux et deux et deux et deux) et (quatorze plus quatorze plus quatorze plus quatorze plus quatorze plus quatorze))',\n",
       " 93: '((trois plus trois plus trois) et (quatorze plus quatorze plus quatorze plus quatorze plus quatorze plus quatorze))',\n",
       " 94: '((quatre plus quatre plus quatre plus quatre) et (treize plus treize plus treize plus treize plus treize plus treize))',\n",
       " 96: '((deux et deux et deux et deux et deux et deux) plus (quatorze et quatorze et quatorze et quatorze et quatorze et quatorze))',\n",
       " 97: '((dix-sept plus dix-sept plus dix-sept plus dix-sept plus dix-sept) et (deux plus deux plus deux plus deux plus deux plus deux))',\n",
       " 98: '((quatre et quatre et quatre et quatre et quatre) plus (treize plus treize plus treize plus treize plus treize plus treize))',\n",
       " 99: '((vingt-trois et vingt-trois et vingt-trois et vingt-trois et vingt-trois) moins (quatre plus quatre plus quatre plus quatre))',\n",
       " 100: '((quatre et quatre et quatre et quatre) et (quatorze plus quatorze plus quatorze plus quatorze plus quatorze plus quatorze))',\n",
       " 101: '((vingt-six plus vingt-six plus vingt-six plus vingt-six plus vingt-six plus vingt-six) moins (onze et onze et onze et onze et onze))',\n",
       " 102: '((zéro plus zéro plus zéro plus zéro plus zéro) plus (dix-sept plus dix-sept plus dix-sept plus dix-sept plus dix-sept plus dix-sept))',\n",
       " 103: '((dix-sept plus dix-sept plus dix-sept plus dix-sept plus dix-sept) et (trois plus trois plus trois plus trois plus trois plus trois))',\n",
       " 104: '((vingt-huit plus vingt-huit plus vingt-huit plus vingt-huit plus vingt-huit) moins (six plus six plus six plus six plus six plus six))',\n",
       " 105: '((vingt-cinq et vingt-cinq et vingt-cinq et vingt-cinq et vingt-cinq et vingt-cinq) moins (neuf plus neuf plus neuf plus neuf plus neuf))',\n",
       " 107: '((vingt-sept plus vingt-sept plus vingt-sept plus vingt-sept plus vingt-sept plus vingt-sept) moins (onze et onze et onze et onze et onze))',\n",
       " 108: '((zéro plus zéro plus zéro plus zéro plus zéro plus zéro) et (dix-huit plus dix-huit plus dix-huit plus dix-huit plus dix-huit plus dix-huit))',\n",
       " 109: '((dix-sept plus dix-sept plus dix-sept plus dix-sept plus dix-sept) et (quatre plus quatre plus quatre plus quatre plus quatre plus quatre))',\n",
       " 110: '((vingt-huit plus vingt-huit plus vingt-huit plus vingt-huit plus vingt-huit) moins (cinq plus cinq plus cinq plus cinq plus cinq plus cinq))',\n",
       " 111: '((vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre) moins (onze plus onze plus onze))',\n",
       " 113: '((vingt-trois plus vingt-trois plus vingt-trois plus vingt-trois plus vingt-trois plus vingt-trois) moins (cinq et cinq et cinq et cinq et cinq))',\n",
       " 114: '((quatre plus quatre plus quatre plus quatre plus quatre plus quatre) et (quinze plus quinze plus quinze plus quinze plus quinze plus quinze))',\n",
       " 115: '((vingt-trois plus vingt-trois plus vingt-trois plus vingt-trois plus vingt-trois) moins (zéro plus zéro plus zéro plus zéro plus zéro plus zéro))',\n",
       " 119: '((vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre) moins (cinq et cinq et cinq et cinq et cinq))',\n",
       " 120: '((vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre plus vingt-quatre) moins (zéro plus zéro plus zéro plus zéro plus zéro plus zéro))'}"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time show(extended(french), 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extended Italian"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extended Italian has 91 equilengths: 3, 9-13, 15-28, 30-64, 66-78, 80-87, 89-92, 94-96, 99, 104-105, 108, 114, 116, 124, 128\n",
      "     from 58,522 table entries in 1 iterations\n",
      "CPU times: user 1.1 s, sys: 14 ms, total: 1.12 s\n",
      "Wall time: 1.13 s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{3: 'tre',\n",
       " 9: '(tre piu sei)',\n",
       " 10: '(uno piu nove)',\n",
       " 11: '(uno piu dieci)',\n",
       " 12: '(uno per dodici)',\n",
       " 13: '(uno per tredici)',\n",
       " 15: '(tre piu (sei piu sei))',\n",
       " 16: '(otto per (uno piu uno))',\n",
       " 17: '(uno piu (otto piu otto))',\n",
       " 18: '(zero piu (nove piu nove))',\n",
       " 19: '(tredici piu (tre piu tre))',\n",
       " 20: '(zero piu (dieci piu dieci))',\n",
       " 21: '(tre piu (sei piu sei piu sei))',\n",
       " 22: '(zero piu (undici piu undici))',\n",
       " 23: '(venti piu (uno piu uno piu uno))',\n",
       " 24: '(uno per (otto piu otto piu otto))',\n",
       " 25: '(venticinque piu (zero piu zero))',\n",
       " 26: '(ventitre piu (uno piu uno piu uno))',\n",
       " 27: '(tre piu (sei piu sei piu sei piu sei))',\n",
       " 28: '(quattro piu (otto piu otto piu otto))',\n",
       " 30: '((tre piu tre) piu (otto piu otto piu otto))',\n",
       " 31: '(tre piu (quattrodici piu quattrodici))',\n",
       " 32: '(zero piu (otto piu otto piu otto piu otto))',\n",
       " 33: '(tre piu (sei piu sei piu sei piu sei piu sei))',\n",
       " 34: '((ventisei piu ventisei) meno (nove piu nove))',\n",
       " 35: '(venti piu (tre piu tre piu tre piu tre piu tre))',\n",
       " 36: '(otto piu (sette piu sette piu sette piu sette))',\n",
       " 37: '((ventiquattro piu ventiquattro) meno undici)',\n",
       " 38: '(ventitre piu (tre piu tre piu tre piu tre piu tre))',\n",
       " 39: '(tre piu (sei piu sei piu sei piu sei piu sei piu sei))',\n",
       " 40: '((ventinove piu ventinove) meno (sei piu sei piu sei))',\n",
       " 41: '((diciotto piu diciotto piu diciotto) meno tredici)',\n",
       " 42: '(trenta piu (due piu due piu due piu due piu due piu due))',\n",
       " 43: '((quindici piu quindici piu quindici) meno (uno piu uno))',\n",
       " 44: '(ventisei piu (tre piu tre piu tre piu tre piu tre piu tre))',\n",
       " 45: '(dieci piu (sette piu sette piu sette piu sette piu sette))',\n",
       " 46: '(undici piu (sette piu sette piu sette piu sette piu sette))',\n",
       " 47: '((quattro piu quattro) piu (tredici piu tredici piu tredici))',\n",
       " 48: '((dodici piu dodici piu dodici) piu (tre piu tre piu tre piu tre))',\n",
       " 49: '((ventidue piu ventidue) piu (uno piu uno piu uno piu uno piu uno))',\n",
       " 50: '((cinque piu cinque) piu (otto piu otto piu otto piu otto piu otto))',\n",
       " 51: '((otto piu otto) piu (sette piu sette piu sette piu sette piu sette))',\n",
       " 52: '((nove piu nove piu nove piu nove piu nove piu nove) meno (uno piu uno))',\n",
       " 53: '(ventotto piu (cinque piu cinque piu cinque piu cinque piu cinque))',\n",
       " 54: '(dodici piu (sette piu sette piu sette piu sette piu sette piu sette))',\n",
       " 55: '(tredici piu (sette piu sette piu sette piu sette piu sette piu sette))',\n",
       " 56: '((diciotto piu diciotto piu diciotto piu diciotto) meno (otto piu otto))',\n",
       " 57: '((uno piu uno piu uno) piu (nove piu nove piu nove piu nove piu nove piu nove))',\n",
       " 58: '((diciotto piu diciotto piu diciotto piu diciotto) meno (sette piu sette))',\n",
       " 59: '(tre piu (quattrodici piu quattrodici piu quattrodici piu quattrodici))',\n",
       " 60: '(trenta piu (cinque piu cinque piu cinque piu cinque piu cinque piu cinque))',\n",
       " 61: '((ventidue piu ventidue piu ventidue) meno (uno piu uno piu uno piu uno piu uno))',\n",
       " 62: '((ventidue piu ventidue piu ventidue piu ventidue) meno (tredici piu tredici))',\n",
       " 63: '((uno piu uno piu uno) piu (dieci piu dieci piu dieci piu dieci piu dieci piu dieci))',\n",
       " 64: '((sedici piu sedici piu sedici) piu (quattro piu quattro piu quattro piu quattro))',\n",
       " 66: '((otto piu otto piu otto) piu (sette piu sette piu sette piu sette piu sette piu sette))',\n",
       " 67: '((tredici piu tredici piu tredici piu tredici) piu (tre piu tre piu tre piu tre piu tre))',\n",
       " 68: '((venti piu venti piu venti piu venti piu venti piu venti) meno (ventisei piu ventisei))',\n",
       " 69: '((uno piu uno piu uno) piu (undici piu undici piu undici piu undici piu undici piu undici))',\n",
       " 70: '((venticinque piu venticinque piu venticinque) meno (uno piu uno piu uno piu uno piu uno))',\n",
       " 71: '((dicinove piu dicinove piu dicinove piu dicinove piu dicinove) meno (dodici piu dodici))',\n",
       " 72: '((zero piu zero piu zero) piu (dodici piu dodici piu dodici piu dodici piu dodici piu dodici))',\n",
       " 73: '(tre piu (quattrodici piu quattrodici piu quattrodici piu quattrodici piu quattrodici))',\n",
       " 74: '((ventisette piu ventisette piu ventisette piu ventisette) meno (dicisette piu dicisette))',\n",
       " 75: '((tre piu tre piu tre piu tre piu tre) piu (dieci piu dieci piu dieci piu dieci piu dieci piu dieci))',\n",
       " 76: '((dicinove piu dicinove piu dicinove piu dicinove) piu (zero piu zero piu zero piu zero piu zero))',\n",
       " 77: '((quattro piu quattro piu quattro) piu (tredici piu tredici piu tredici piu tredici piu tredici))',\n",
       " 78: '((zero piu zero piu zero) piu (tredici piu tredici piu tredici piu tredici piu tredici piu tredici))',\n",
       " 80: '((dicinove piu dicinove piu dicinove piu dicinove piu dicinove) meno (cinque piu cinque piu cinque))',\n",
       " 81: '((tre piu tre piu tre piu tre piu tre) piu (undici piu undici piu undici piu undici piu undici piu undici))',\n",
       " 82: '((dicinove piu dicinove piu dicinove piu dicinove piu dicinove piu dicinove) meno (sedici piu sedici))',\n",
       " 83: '((tredici piu tredici piu tredici piu tredici piu tredici) piu (tre piu tre piu tre piu tre piu tre piu tre))',\n",
       " 84: '((diciotto piu diciotto piu diciotto) piu (cinque piu cinque piu cinque piu cinque piu cinque piu cinque))',\n",
       " 85: '((zero piu zero piu zero piu zero) piu (dicisette piu dicisette piu dicisette piu dicisette piu dicisette))',\n",
       " 86: '((ventotto piu ventotto piu ventotto piu ventotto piu ventotto) meno (diciotto piu diciotto piu diciotto))',\n",
       " 87: '(tre piu (quattrodici piu quattrodici piu quattrodici piu quattrodici piu quattrodici piu quattrodici))',\n",
       " 89: '((dicinove piu dicinove piu dicinove piu dicinove piu dicinove) meno (uno piu uno piu uno piu uno piu uno piu uno))',\n",
       " 90: '((ventidue piu ventidue piu ventidue) piu (quattro piu quattro piu quattro piu quattro piu quattro piu quattro))',\n",
       " 91: '((sette piu sette piu sette) piu (quattrodici piu quattrodici piu quattrodici piu quattrodici piu quattrodici))',\n",
       " 92: '((ventotto piu ventotto piu ventotto piu ventotto) meno (quattro piu quattro piu quattro piu quattro piu quattro))',\n",
       " 94: '((dicisette piu dicisette piu dicisette piu dicisette piu dicisette piu dicisette) meno (due piu due piu due piu due))',\n",
       " 95: '((dicinove piu dicinove piu dicinove piu dicinove piu dicinove) meno (zero piu zero piu zero piu zero piu zero piu zero))',\n",
       " 96: '((ventinove piu ventinove piu ventinove piu ventinove) meno (quattro piu quattro piu quattro piu quattro piu quattro))',\n",
       " 99: '((ventisette piu ventisette piu ventisette piu ventisette piu ventisette) meno (sei piu sei piu sei piu sei piu sei piu sei))',\n",
       " 104: '((ventisei piu ventisei piu ventisei piu ventisei piu ventisei piu ventisei) meno (tredici piu tredici piu tredici piu tredici))',\n",
       " 105: '((sette piu sette piu sette) piu (quattrodici piu quattrodici piu quattrodici piu quattrodici piu quattrodici piu quattrodici))',\n",
       " 108: '((ventotto piu ventotto piu ventotto piu ventotto piu ventotto piu ventotto) meno (quindici piu quindici piu quindici piu quindici))',\n",
       " 114: '((ventinove piu ventinove piu ventinove piu ventinove piu ventinove piu ventinove) meno (quindici piu quindici piu quindici piu quindici))',\n",
       " 116: '((ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro) meno (quattrodici piu quattrodici))',\n",
       " 124: '((ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro) meno (cinque piu cinque piu cinque piu cinque))',\n",
       " 128: '((ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro piu ventiquattro) meno (quattro piu quattro piu quattro piu quattro))'}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time show(extended(italian), 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extended Chinese\n",
    "\n",
    "Since the Chinese number names tend to be shorter, I'll allow more repetitions in `extended`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extended Chinese has 119 equilengths: 2-3, 7-106, 108-111, 114-116, 120, 123, 125-126, 128, 133, 136-138, 142\n",
      "     from 156,099 table entries in 1 iterations\n",
      "CPU times: user 4.12 s, sys: 49.3 ms, total: 4.17 s\n",
      "Wall time: 4.21 s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{2: 'èr',\n",
       " 3: 'sān',\n",
       " 7: '(èr jiā wŭ)',\n",
       " 8: '(èr jiā liù)',\n",
       " 9: '(sān jiā liù)',\n",
       " 10: '(yī chéng shí)',\n",
       " 11: '(shí bā jiǎn qī)',\n",
       " 12: '(èr jiā (wŭ jiā wŭ))',\n",
       " 13: '(sān jiā (wŭ jiā wŭ))',\n",
       " 14: '(yī chéng (qī jiā qī))',\n",
       " 15: '(sān jiā (liù jiā liù))',\n",
       " 16: '(èr shí jiǎn (èr jiā èr))',\n",
       " 17: '(èr jiā (wŭ jiā wŭ jiā wŭ))',\n",
       " 18: '(sān jiā (wŭ jiā wŭ jiā wŭ))',\n",
       " 19: '(èr shí jiŭ jiǎn (wŭ jiā wŭ))',\n",
       " 20: '(èr jiā (liù jiā liù jiā liù))',\n",
       " 21: '(sān jiā (liù jiā liù jiā liù))',\n",
       " 22: '(èr jiā (wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 23: '(sān jiā (wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 24: '((yī jiā yī) chéng (sì jiā sì jiā sì))',\n",
       " 25: '(shí qī jiā (èr jiā èr jiā èr jiā èr))',\n",
       " 26: '(èr jiā (liù jiā liù jiā liù jiā liù))',\n",
       " 27: '(èr jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 28: '(sān jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 29: '(shí qī jiā (sān jiā sān jiā sān jiā sān))',\n",
       " 30: '(sān chéng (èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 31: '((shí yī jiā shí yī) jiā (sān jiā sān jiā sān))',\n",
       " 32: '(bā jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 33: '(jiŭ jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 34: '((shí qī jiā shí qī) jiā (ling jiā ling jiā ling))',\n",
       " 35: '(shí yī jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 36: '(sān shí jiā (yī jiā yī jiā yī jiā yī jiā yī jiā yī))',\n",
       " 37: '(èr jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 38: '(sān jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 39: '(sān jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 40: '(shí èr jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 41: '(shí sān jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 42: '(èr jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 43: '(sān jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 44: '(èr jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 45: '(sān jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 46: '(sān shí jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 47: '(èr jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 48: '(sān jiā (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 49: '(èr shí bā jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 50: '(shí sì jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 51: '(sān jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 52: '((bā jiā bā) jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 53: '((èr shí yī jiā èr shí yī jiā èr shí yī) jiǎn (èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 54: '((jiŭ jiā jiŭ) jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 55: '((shí qī jiā shí qī) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 56: '(èr jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 57: '(sān jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 58: '((shí yī jiā shí yī) jiā (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 59: '((shí yī jiā shí yī jiā shí yī jiā shí yī) jiā (sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 60: '((sì jiā sì jiā sì) jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 61: '((shí wǔ jiā shí wǔ jiā shí wǔ) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 62: '((èr shí èr jiā èr shí èr) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 63: '((ling jiā ling jiā ling) jiā (qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī))',\n",
       " 64: '((èr shí sān jiā èr shí sān) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 65: '((shí bā jiā shí bā jiā shí bā jiā shí bā) jiǎn (yī jiā yī jiā yī jiā yī jiā yī jiā yī jiā yī))',\n",
       " 66: '((sì jiā sì jiā sì) jiā (liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 67: '((èr shí jiā èr shí) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 68: '((èr shí bā jiā èr shí bā jiā èr shí bā) jiǎn (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 69: '((shí wǔ jiā shí wǔ jiā shí wǔ) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 70: '((shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì) jiǎn (shí sì jiā shí sì))',\n",
       " 71: '((èr shí èr jiā èr shí èr) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 72: '((èr shí yī jiā èr shí yī jiā èr shí yī) jiā (yī jiā yī jiā yī jiā yī jiā yī jiā yī jiā yī jiā yī jiā yī))',\n",
       " 73: '((èr shí sān jiā èr shí sān) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 74: '((shí sì jiā shí sì jiā shí sì jiā shí sì) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 75: '((jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 76: '((shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ) jiǎn (ling jiā ling jiā ling jiā ling jiā ling jiā ling))',\n",
       " 77: '((èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr) jiā (qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī))',\n",
       " 78: '((shí jiā shí jiā shí jiā shí jiā shí jiā shí) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 79: '((jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 80: '((ling jiā ling jiā ling jiā ling jiā ling) jiā (shí jiā shí jiā shí jiā shí jiā shí jiā shí jiā shí jiā shí))',\n",
       " 81: '((shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā) chú yǐ (yī jiā yī))',\n",
       " 82: '((bā jiā bā jiā bā jiā bā jiā bā jiā bā jiā bā jiā bā) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 83: '((shí sì jiā shí sì jiā shí sì jiā shí sì) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 84: '((sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān) jiā (qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī jiā qī))',\n",
       " 85: '((èr shí jiŭ jiā èr shí jiŭ jiā èr shí jiŭ jiā èr shí jiŭ jiā èr shí jiŭ) jiǎn (shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ))',\n",
       " 86: '((shí qī jiā shí qī jiā shí qī jiā shí qī jiā shí qī jiā shí qī) jiǎn (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 87: '((shí jiā shí jiā shí jiā shí jiā shí jiā shí) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 88: '((èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì) jiǎn (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 89: '((shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān) jiǎn èr shí bā)',\n",
       " 90: '((jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 91: '((bā jiā bā jiā bā jiā bā jiā bā jiā bā jiā bā jiā bā) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 92: '((sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí) jiǎn (èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr))',\n",
       " 93: '((shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 94: '((shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā) jiǎn (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 95: '((shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ) jiǎn (bā jiā bā jiā bā jiā bā jiā bā))',\n",
       " 96: '((shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 97: '((shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ) jiǎn (liù jiā liù jiā liù jiā liù jiā liù jiā liù))',\n",
       " 98: '((èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī) jiǎn (bā jiā bā jiā bā jiā bā jiā bā jiā bā jiā bā jiā bā))',\n",
       " 99: '((jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ jiā jiŭ) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 100: '((èr shí jiā èr shí jiā èr shí jiā èr shí jiā èr shí) jiā (ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling))',\n",
       " 101: '((shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ) jiǎn (sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì jiā sì))',\n",
       " 102: '((shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā) jiǎn (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 103: '((èr shí bā jiā èr shí bā jiā èr shí bā jiā èr shí bā jiā èr shí bā jiā èr shí bā) jiǎn (shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān))',\n",
       " 104: '((èr shí liù jiā èr shí liù jiā èr shí liù jiā èr shí liù) jiā (ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling))',\n",
       " 105: '((shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 106: '((shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī) jiā (èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr jiā èr))',\n",
       " 108: '((shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā jiā shí bā) jiā (ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling))',\n",
       " 109: '((shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ) jiǎn (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 110: '((èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr) jiā (ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling))',\n",
       " 111: '((shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ) jiǎn (shí wǔ jiā shí wǔ jiā shí wǔ jiā shí wǔ))',\n",
       " 114: '((shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ jiā shí jiŭ) jiā (ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling))',\n",
       " 115: '((shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī jiā shí yī) jiā (sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān jiā sān))',\n",
       " 116: '((èr shí bā jiā èr shí bā jiā èr shí bā jiā èr shí bā jiā èr shí bā jiā èr shí bā jiā èr shí bā) jiǎn (shí jiā shí jiā shí jiā shí jiā shí jiā shí jiā shí jiā shí))',\n",
       " 120: '((sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí) jiǎn (èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì))',\n",
       " 123: '((èr shí yī jiā èr shí yī jiā èr shí yī jiā èr shí yī jiā èr shí yī jiā èr shí yī jiā èr shí yī jiā èr shí yī) jiǎn (wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ jiā wŭ))',\n",
       " 125: '((sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí jiā sān shí) jiǎn (èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān))',\n",
       " 126: '((shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì) jiǎn (ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling jiā ling))',\n",
       " 128: '((èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr) jiǎn (shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì))',\n",
       " 133: '((èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr jiā èr shí èr) jiǎn (shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān))',\n",
       " 136: '((èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì jiā èr shí sì) jiǎn (shí jiā shí jiā shí jiā shí jiā shí jiā shí jiā shí jiā shí))',\n",
       " 137: '((èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān) jiǎn (shí sì jiā shí sì jiā shí sì jiā shí sì jiā shí sì))',\n",
       " 138: '((èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī jiā èr shí qī) jiǎn (èr shí yī jiā èr shí yī jiā èr shí yī jiā èr shí yī jiā èr shí yī))',\n",
       " 142: '((èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān jiā èr shí sān) jiǎn (shí sān jiā shí sān jiā shí sān jiā shí sān jiā shí sān))'}"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time show(extended(chinese, 9), 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extended German"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extended German has 139 equilengths: 4, 11-13, 15-138, 140, 143-146, 150-152, 156-157, 162\n",
      "     from 157,788 table entries in 1 iterations\n",
      "CPU times: user 7.31 s, sys: 79.2 ms, total: 7.39 s\n",
      "Wall time: 7.45 s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{4: 'vier',\n",
       " 11: '(null plus elf)',\n",
       " 12: '(eins mal zwölf)',\n",
       " 13: '(eins plus zwölf)',\n",
       " 15: '(eins mal funfzehn)',\n",
       " 16: '(eins mal sechszehn)',\n",
       " 17: '(elf und (drei und drei))',\n",
       " 18: '(eins mal (neun und neun))',\n",
       " 19: '(eins und (neun plus neun))',\n",
       " 20: '(null plus (zehn plus zehn))',\n",
       " 21: '(neun und (sechs plus sechs))',\n",
       " 22: '(acht und (sieben und sieben))',\n",
       " 23: '(neun und (sieben plus sieben))',\n",
       " 24: '((eins und eins) und (elf plus elf))',\n",
       " 25: '(eins und (acht und acht und acht))',\n",
       " 26: '(zwei plus (acht und acht und acht))',\n",
       " 27: '(eins mal (neun plus neun plus neun))',\n",
       " 28: '(eins plus (neun plus neun plus neun))',\n",
       " 29: '(elf und (sechs plus sechs plus sechs))',\n",
       " 30: '(zwölf plus (sechs und sechs und sechs))',\n",
       " 31: '(elf und (fünf und fünf und fünf und fünf))',\n",
       " 32: '(eins mal (acht und acht und acht und acht))',\n",
       " 33: '(eins plus (acht und acht und acht und acht))',\n",
       " 34: '((zwei plus zwei) plus (zehn und zehn und zehn))',\n",
       " 35: '(drei und (acht plus acht plus acht plus acht))',\n",
       " 36: '(null plus (neun plus neun plus neun plus neun))',\n",
       " 37: '(siebzehn plus (fünf und fünf und fünf und fünf))',\n",
       " 38: '((elf plus elf) und (vier und vier und vier und vier))',\n",
       " 39: '(elf und (sieben und sieben und sieben und sieben))',\n",
       " 40: '(null plus (acht und acht und acht und acht und acht))',\n",
       " 41: '(siebzehn plus (sechs und sechs und sechs und sechs))',\n",
       " 42: '((eins und eins) und (zehn plus zehn plus zehn plus zehn))',\n",
       " 43: '(drei und (acht plus acht plus acht plus acht plus acht))',\n",
       " 44: '(vier plus (acht plus acht plus acht plus acht plus acht))',\n",
       " 45: '(siebzehn plus (sieben und sieben und sieben und sieben))',\n",
       " 46: '((drei und drei) und (acht und acht und acht und acht und acht))',\n",
       " 47: '((eins plus eins plus eins) und (elf plus elf plus elf plus elf))',\n",
       " 48: '((vier plus vier) plus (acht und acht und acht und acht und acht))',\n",
       " 49: '(neunzehn plus (sechs und sechs und sechs und sechs und sechs))',\n",
       " 50: '(zwanzig plus (fünf und fünf und fünf und fünf und fünf und fünf))',\n",
       " 51: '(drei und (acht plus acht plus acht plus acht plus acht plus acht))',\n",
       " 52: '(vier plus (acht plus acht plus acht plus acht plus acht plus acht))',\n",
       " 53: '(achtzehn und (sieben und sieben und sieben und sieben und sieben))',\n",
       " 54: '((null plus null) und (neun und neun und neun und neun und neun und neun))',\n",
       " 55: '((null plus null plus null) plus (elf plus elf plus elf plus elf plus elf))',\n",
       " 56: '(zwanzig plus (sechs und sechs und sechs und sechs und sechs und sechs))',\n",
       " 57: '((elf und elf und elf) und (vier und vier und vier und vier und vier und vier))',\n",
       " 58: '((zwei und zwei) und (neun plus neun plus neun plus neun plus neun plus neun))',\n",
       " 59: '((eins und eins und eins und eins) und (elf plus elf plus elf plus elf plus elf))',\n",
       " 60: '((null und null und null) und (zehn und zehn und zehn und zehn und zehn und zehn))',\n",
       " 61: '((sieben plus sieben plus sieben) und (acht und acht und acht und acht und acht))',\n",
       " 62: '((sieben und sieben) und (acht plus acht plus acht plus acht plus acht plus acht))',\n",
       " 63: '((eins plus eins plus eins) plus (zehn und zehn und zehn und zehn und zehn und zehn))',\n",
       " 64: '((elf plus elf) und (sieben und sieben und sieben und sieben und sieben und sieben))',\n",
       " 65: '((fünf und fünf und fünf und fünf) plus (neun plus neun plus neun plus neun plus neun))',\n",
       " 66: '((null und null und null und null) und (elf plus elf plus elf plus elf plus elf plus elf))',\n",
       " 67: '((eins plus eins) und (dreizehn und dreizehn und dreizehn und dreizehn und dreizehn))',\n",
       " 68: '((zwei und zwei und zwei und zwei) plus (zehn und zehn und zehn und zehn und zehn und zehn))',\n",
       " 69: '((sieben plus sieben plus sieben) plus (acht und acht und acht und acht und acht und acht))',\n",
       " 70: '((eins plus eins plus eins plus eins) plus (elf plus elf plus elf plus elf plus elf plus elf))',\n",
       " 71: '((drei plus drei) und (dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn))',\n",
       " 72: '((sechs und sechs und sechs und sechs) plus (acht und acht und acht und acht und acht und acht))',\n",
       " 73: '((elf plus elf plus elf plus elf plus elf) und (drei und drei und drei und drei und drei und drei))',\n",
       " 74: '((vier und vier und vier und vier und vier) und (neun und neun und neun und neun und neun und neun))',\n",
       " 75: '((drei und drei und drei und drei und drei) plus (zehn und zehn und zehn und zehn und zehn und zehn))',\n",
       " 76: '((eins plus eins plus eins plus eins) und (zwölf und zwölf und zwölf und zwölf und zwölf und zwölf))',\n",
       " 77: '((vier und vier und vier) und (dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn))',\n",
       " 78: '((null plus null) und (dreizehn und dreizehn und dreizehn und dreizehn und dreizehn und dreizehn))',\n",
       " 79: '((fünf und fünf und fünf und fünf und fünf) und (neun plus neun plus neun plus neun plus neun plus neun))',\n",
       " 80: '((neunzehn plus neunzehn) plus (sieben plus sieben plus sieben plus sieben plus sieben plus sieben))',\n",
       " 81: '((neun und neun und neun und neun und neun) plus (sechs und sechs und sechs und sechs und sechs und sechs))',\n",
       " 82: '((zwei und zwei) und (dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn))',\n",
       " 83: '((eins und eins und eins) plus (sechszehn plus sechszehn plus sechszehn plus sechszehn plus sechszehn))',\n",
       " 84: '((null plus null) plus (vierzehn plus vierzehn plus vierzehn plus vierzehn plus vierzehn plus vierzehn))',\n",
       " 85: '((null und null und null und null) plus (siebzehn plus siebzehn plus siebzehn plus siebzehn plus siebzehn))',\n",
       " 86: '((zweiundzwanzig plus zweiundzwanzig) und (sieben und sieben und sieben und sieben und sieben und sieben))',\n",
       " 87: '((eins plus eins plus eins) plus (vierzehn und vierzehn und vierzehn und vierzehn und vierzehn und vierzehn))',\n",
       " 88: '((sechsundzwanzig plus sechsundzwanzig) plus (sechs plus sechs plus sechs plus sechs plus sechs plus sechs))',\n",
       " 89: '((sieben und sieben und sieben und sieben und sieben) und (neun plus neun plus neun plus neun plus neun plus neun))',\n",
       " 90: '((null und null und null) plus (funfzehn plus funfzehn plus funfzehn plus funfzehn plus funfzehn plus funfzehn))',\n",
       " 91: '((vierzehn und vierzehn und vierzehn und vierzehn) plus (sieben plus sieben plus sieben plus sieben plus sieben))',\n",
       " 92: '((zwei und zwei und zwei und zwei) plus (vierzehn und vierzehn und vierzehn und vierzehn und vierzehn und vierzehn))',\n",
       " 93: '((einundzwanzig und einundzwanzig und einundzwanzig) plus (fünf plus fünf plus fünf plus fünf plus fünf plus fünf))',\n",
       " 94: '((eins plus eins plus eins plus eins) und (funfzehn und funfzehn und funfzehn und funfzehn und funfzehn und funfzehn))',\n",
       " 95: '((dreizehn und dreizehn und dreizehn und dreizehn und dreizehn) plus (fünf und fünf und fünf und fünf und fünf und fünf))',\n",
       " 96: '((null und null und null) plus (sechszehn plus sechszehn plus sechszehn plus sechszehn plus sechszehn plus sechszehn))',\n",
       " 97: '((einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig) minus (vier und vier))',\n",
       " 98: '((vier und vier und vier und vier und vier) und (dreizehn und dreizehn und dreizehn und dreizehn und dreizehn und dreizehn))',\n",
       " 99: '((drei und drei und drei und drei und drei) plus (vierzehn und vierzehn und vierzehn und vierzehn und vierzehn und vierzehn))',\n",
       " 100: '((eins plus eins plus eins plus eins) und (sechszehn und sechszehn und sechszehn und sechszehn und sechszehn und sechszehn))',\n",
       " 101: '((dreizehn und dreizehn und dreizehn und dreizehn und dreizehn) plus (sechs und sechs und sechs und sechs und sechs und sechs))',\n",
       " 102: '((null plus null plus null plus null plus null) und (siebzehn und siebzehn und siebzehn und siebzehn und siebzehn und siebzehn))',\n",
       " 103: '((fünf und fünf und fünf und fünf und fünf) und (dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn))',\n",
       " 104: '((vier und vier und vier und vier und vier) plus (vierzehn plus vierzehn plus vierzehn plus vierzehn plus vierzehn plus vierzehn))',\n",
       " 105: '((einundzwanzig und einundzwanzig und einundzwanzig) plus (sieben plus sieben plus sieben plus sieben plus sieben plus sieben))',\n",
       " 106: '((vierzehn und vierzehn und vierzehn und vierzehn und vierzehn) plus (sechs plus sechs plus sechs plus sechs plus sechs plus sechs))',\n",
       " 107: '((eins plus eins plus eins plus eins plus eins) und (siebzehn plus siebzehn plus siebzehn plus siebzehn plus siebzehn plus siebzehn))',\n",
       " 108: '((null plus null plus null plus null plus null) plus (achtzehn plus achtzehn plus achtzehn plus achtzehn plus achtzehn plus achtzehn))',\n",
       " 109: '((eins und eins und eins und eins) und (einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig))',\n",
       " 110: '((dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig) und (drei und drei und drei und drei und drei und drei))',\n",
       " 111: '((neunundzwanzig plus neunundzwanzig plus neunundzwanzig plus neunundzwanzig) weniger (eins plus eins plus eins plus eins plus eins))',\n",
       " 112: '((vierzehn und vierzehn und vierzehn und vierzehn und vierzehn) plus (sieben plus sieben plus sieben plus sieben plus sieben plus sieben))',\n",
       " 113: '((sieben und sieben und sieben und sieben und sieben) und (dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn plus dreizehn))',\n",
       " 114: '((neunzehn und neunzehn und neunzehn und neunzehn und neunzehn und neunzehn) weniger (null plus null plus null plus null plus null plus null))',\n",
       " 115: '((null und null und null und null) plus (dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig))',\n",
       " 116: '((dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig) plus (vier plus vier plus vier plus vier plus vier plus vier))',\n",
       " 117: '((fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig) weniger (zwei plus zwei plus zwei plus zwei))',\n",
       " 118: '((zwei plus zwei plus zwei plus zwei) plus (zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig))',\n",
       " 119: '((achtundzwanzig plus achtundzwanzig plus achtundzwanzig plus achtundzwanzig plus achtundzwanzig) weniger (sieben plus sieben plus sieben))',\n",
       " 120: '((siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig) und (zwei plus zwei plus zwei plus zwei plus zwei plus zwei))',\n",
       " 121: '((neunundzwanzig und neunundzwanzig und neunundzwanzig und neunundzwanzig und neunundzwanzig) weniger (sechs plus sechs plus sechs plus sechs))',\n",
       " 122: '((sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig) weniger (zwei plus zwei plus zwei plus zwei))',\n",
       " 123: '((einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig) und (drei und drei und drei und drei und drei und drei))',\n",
       " 124: '((fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig) minus (dreizehn plus dreizehn))',\n",
       " 125: '((fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig) plus (null und null und null und null und null und null))',\n",
       " 126: '((null und null und null und null) und (einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig))',\n",
       " 127: '((siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig) weniger (zwei plus zwei plus zwei plus zwei))',\n",
       " 128: '((zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig) und (drei und drei und drei und drei und drei und drei))',\n",
       " 129: '((einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig) plus (vier plus vier plus vier plus vier plus vier plus vier))',\n",
       " 130: '((eins plus eins plus eins plus eins) plus (einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig plus einundzwanzig))',\n",
       " 131: '((siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig) weniger (eins plus eins plus eins plus eins))',\n",
       " 132: '((null und null und null und null) und (zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig))',\n",
       " 133: '((dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig) und (drei plus drei plus drei plus drei plus drei plus drei))',\n",
       " 134: '((zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig) plus (vier plus vier plus vier plus vier plus vier plus vier))',\n",
       " 135: '((siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig) plus (null und null und null und null und null und null))',\n",
       " 136: '((eins plus eins plus eins plus eins) plus (zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig plus zweiundzwanzig))',\n",
       " 137: '((siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig) weniger fünfundzwanzig)',\n",
       " 138: '((null plus null plus null plus null plus null) und (dreiundzwanzig und dreiundzwanzig und dreiundzwanzig und dreiundzwanzig und dreiundzwanzig und dreiundzwanzig))',\n",
       " 140: '((fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig und fünfundzwanzig) minus (zwei plus zwei plus zwei plus zwei plus zwei))',\n",
       " 143: '((eins plus eins plus eins plus eins plus eins) und (dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig plus dreiundzwanzig))',\n",
       " 144: '((null plus null plus null plus null plus null) plus (vierundzwanzig plus vierundzwanzig plus vierundzwanzig plus vierundzwanzig plus vierundzwanzig plus vierundzwanzig))',\n",
       " 145: '((fünfundzwanzig plus fünfundzwanzig plus fünfundzwanzig plus fünfundzwanzig plus fünfundzwanzig plus fünfundzwanzig) minus (eins plus eins plus eins plus eins plus eins))',\n",
       " 146: '((sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig) minus (zwei plus zwei plus zwei plus zwei plus zwei))',\n",
       " 150: '((neunundzwanzig und neunundzwanzig und neunundzwanzig und neunundzwanzig und neunundzwanzig und neunundzwanzig) weniger (vier plus vier plus vier plus vier plus vier plus vier))',\n",
       " 151: '((sechsundzwanzig plus sechsundzwanzig plus sechsundzwanzig plus sechsundzwanzig plus sechsundzwanzig plus sechsundzwanzig) minus (eins plus eins plus eins plus eins plus eins))',\n",
       " 152: '((siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig) minus (zwei plus zwei plus zwei plus zwei plus zwei))',\n",
       " 156: '((sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig und sechsundzwanzig) weniger (null plus null plus null plus null plus null plus null))',\n",
       " 157: '((siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig plus siebenundzwanzig) minus (eins plus eins plus eins plus eins plus eins))',\n",
       " 162: '((siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig und siebenundzwanzig) weniger (null plus null plus null plus null plus null plus null))'}"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time show(extended(german), 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That looks pretty good. We're getting more equilength expressions, and they cover the integers pretty well. We could go up to `c=2`, but it would take longer. Perhaps you can figure out a way to make the search more efficient. I'll leave it to you to explore further.\n",
    "\n",
    "# Summary\n",
    "\n",
    "Here is a table of the number of equilength expressions found for each language, for `expressions` with `c=0` and `c=2`, for infinite additions, and for `extended` languages with `c=1`. English has the most on all counts, but I think that is largely because I gave it 11 operator names, while most of the other languages only have 4 or 5. German has the next most, which I believe is due to the fact that German integer names are longer than the other languages, on average.\n",
    "\n",
    "|Language|c=0|c=2|∞|extended, c=1|\n",
    "|---|--|--|--|--|\n",
    "|Mini|1|2|0|6|\n",
    "|English|1|47|3|150|\n",
    "|Spanish|1|41|0|77|\n",
    "|French|0|40|1|107|\n",
    "|Italian|1|32|2|91|\n",
    "|Chinese|2|28|2|119|\n",
    "|German|1|48|1|139|\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
